Source code for Muscat.IO.SamcefReader

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

"""Samcef dat (bank) file reader
"""
import numpy as np

from Muscat.IO.IOFactory import RegisterReaderClass
from Muscat.Helpers.Logger import Debug, Info
import Muscat.Containers.ElementsDescription as ED
from Muscat.IO.ReaderBase import ReaderBase
from Muscat.Helpers import ParserHelper as PH
from Muscat.Types import MuscatFloat, MuscatIndex

KeywordToIgnore = ["INIT",
                   "MCNL",
                   "ASEF",
                   "HYP",
                   "DES",
                   "MAT",
                   "UNIT",
                   "GEL",
                   "SAM",
                   "OPT",
                   "SAI",
                   "UNITE",
                   "PHP",
                   "RBE",
                   "BPR",
                   "FCT",
                   "SUB",
                   "MCT",
                   ]


[docs]def DischardTillNextSection(func): while (True): courrentText = func() if courrentText is None: break if len(courrentText) > 1 and courrentText[0] == ".": break return courrentText
[docs]def LineToList(text): import csv return list(csv.reader([text], delimiter=' ', quotechar='"'))[0]
[docs]def LineToDic(text, res=None): if res is None: res = {} res["&"] = False fields = LineToList(text) cpt = 0 if len(fields[0]) > 0 and fields[0][0] == ".": res["KEYWORD"] = text.split()[0].split(".")[1] cpt += 1 else: res["KEYWORD"] = None # ignored = [] while (cpt < len(fields)): k = fields[cpt] if k in res.keys(): cpt += 1 if type(res[k]) == bool: data = True else: if type(res[k]).__module__ == np.__name__: l = len(res[k]) data = PH.Read(fields[cpt:cpt+l], res[k]) cpt += l else: data = PH.Read(fields[cpt], res[k]) cpt += 1 res[k] = data else: # ignored.append(k) cpt += 1 # if len(ignored): # print("Ignoring : " + str(ignored) ) return res
[docs]class DatReader(ReaderBase): """Samcef dat (bank) Reader class """ def __init__(self): super().__init__() self.commentHeader = "!" self.readFormat = 'r' self.encoding = None
[docs] def ReadCleanLine(self): res = super().ReadCleanLine() if res is None: return None res = res.split("!")[0] if len(res) == 0: return self.ReadCleanLine() # read multiline blocks if res[-1] == "$": nline = self.PeekLine() if nline[0] != ".": return res[:-1] + " " + self.ReadCleanLine() return res
[docs] def Read(self, fileName=None, string=None, out=None): """Function that performs the reading of a samcef bank file Parameters ---------- fileName : str, optional name of the file to be read, by default None string : str, optional data to be read as a string instead of a file, by default None out : Mesh, optional output unstructured mesh object containing reading result, by default None Returns ------- Mesh output unstructured mesh object containing reading result """ import Muscat.FE.ProblemData as ProblemData import Muscat.Containers.Mesh as UM if fileName is not None: self.SetFileName(fileName) if string is not None: self.SetStringToRead(string) self.StartReading() if out is None: res = UM.Mesh() else: res = out meta = ProblemData.ProblemData() filetointernalid = {} filetointernalidElement = {} originalsids = [] xs = [] ys = [] zs = [] def GetInternalNumberFromOriginalid(theList): try: return [filetointernalid[x] for x in theList] except KeyError as e: print("ERROR!!! Node with number " + str(e) + " not in file") raise self.FRAME = {} self.AEL = [] l = self.ReadCleanLine() while True: if l == "RETURN": break if l is None: break ldata = LineToDic(l) if ldata["KEYWORD"] in KeywordToIgnore: Info("Ignoring: " + ldata["KEYWORD"]) l = DischardTillNextSection(self.ReadCleanLine) continue if ldata["KEYWORD"] == "NOE": Info('Reading Nodes') cpt = 0 while (True): l = self.ReadCleanLine() if l is None: break if l[0] == ".": break fields = l.split() if fields[0] == "I": lcpt = 0 while lcpt < len(fields): if fields[lcpt] == "I": oid = int(fields[lcpt+1]) lcpt += 2 elif fields[lcpt] == "X": x = float(fields[lcpt+1]) lcpt += 2 elif fields[lcpt] == "Y": y = float(fields[lcpt+1]) lcpt += 2 elif fields[lcpt] == "Z": z = float(fields[lcpt+1]) lcpt += 2 else: raise else: oid = int(fields[0]) x = float(fields[1]) y = float(fields[2]) z = float(fields[3]) originalsids.append(oid) xs.append(x) ys.append(y) zs.append(z) filetointernalid[oid] = cpt cpt += 1 continue if ldata["KEYWORD"] == "CLM": Info('Reading CLM') cpt = 0 while (True): l = self.ReadCleanLine() if l is None: break if l[0] == ".": break data = {"FIX": False, "NOEUD": False, "I": 0, "C": np.zeros(3, dtype=int), "COMP": 0, "NC": 0.0, "V": 0.0} data = LineToDic(l, data) if data["NOEUD"]: name = "FIX_" + "".join([str(x) for x in data["C"]]) res.nodesTags.CreateTag(name, False).AddToTag(filetointernalid[data["I"]]) elif data["COMP"] > 0 and data["V"] != 0: name = "Force"+str(data["COMP"]) res.nodesTags.CreateTag(name, False).AddToTag(filetointernalid[data["I"]]) continue if ldata["KEYWORD"] == "SEL": l = l[1:] # hack to make the "while l[0] != ..." line work correctly fields = LineToList(l) while l[0] != ".": cpt = 0 onElements = False ALL = False onFace = False tagname = None while (cpt < len(fields)): if fields[cpt] == "GROUP": cpt += 1 group = int(fields[cpt]) cpt += 1 elif fields[cpt] == "NOM": cpt += 1 tagname = fields[cpt] cpt += 1 elif fields[cpt] == "MAILLES": onElements = True cpt += 1 elif fields[cpt][0:6] == "NOEUD": onElements = False cpt += 1 elif fields[cpt] == "FACES": onFace = True break elif fields[cpt] == "TOUT": ALL = True cpt += 1 else: cpt += 1 if onFace: l = DischardTillNextSection(self.ReadCleanLine) Info("Ignoring Group of Faces") break ids = [] while (True): l = self.ReadCleanLine() if l == None: break if l[0] == ".": break fields = LineToList(l) if fields[0] == "GROUP": break ldata = l.split() if ldata[0] == "I": ids.extend(map(int, ldata[1:-1])) elif ldata[0] == "UNION": for name, data in res.elements.items(): if "Group"+str(ldata[1]) in data.tags: tag = data.tags["Group"+str(ldata[1])] ids.extend(data.originalIds[tag.GetIds()]) else: ids.extend(map(int, ldata)) if tagname is None: tagname = "G"+str(group) if onElements: if ALL: for name, data in res.elements.items(): data.tags.CreateTag(tagname).SetIds(np.arange(data.GetNumberOfElements())) else: for oidd in ids: elem, idd = filetointernalidElement[oidd] elem.tags.CreateTag(tagname, False).AddToTag(idd) elem.tags.CreateTag("Group"+str(group), False).AddToTag(idd) else: if ALL: res.nodesTags.CreateTag(tagname).SetIds(np.arange(len(filetointernalid))) res.nodesTags.CreateTag("Group"+str(group)).SetIds(np.arange(len(filetointernalid))) else: oids = [filetointernalid[i] for i in ids] res.nodesTags.CreateTag(tagname).SetIds(oids) res.nodesTags.CreateTag("Group"+str(group)).SetIds(oids) # ".SEL GROUP 1 MAILLES NOM "tagname-1_CORPS_146"" if l == None: break if l[0] == ".": break continue if ldata["KEYWORD"] == "MCE": fields = l.split() if len(fields) == 1: l = self.ReadCleanLine() fields = l.split() fcpt = 0 oid = None ids = None while (fcpt < len(fields)): if fields[fcpt] == "I": fcpt += 1 oid = int(fields[fcpt]) fcpt += 1 etype = fields[fcpt] fcpt += 1 elif fields[fcpt] == "N": fcpt += 1 ids = list(map(int, fields[fcpt:])) else: fcpt += 1 elements = res.GetElementsOfType(ED.Bar_2) conn = GetInternalNumberFromOriginalid(ids[:2]) cid = elements.AddNewElement(conn, oid) filetointernalidElement[oid] = (elements, cid-1) l = self.ReadCleanLine() continue if ldata["KEYWORD"] == "FRAME": Info('Reading frame') cpt = 0 #l = self.ReadCleanLine() l = self.ReadCleanLine() while (True): # for every I entry if l == None: break if l[0] == ".": break # default values __origin = np.array([0., 0., 0.]) __V1 = np.array([1., 0., 0.]) __V2 = np.array([0., 1., 0.]) __V3 = np.array([0., 0., 1.]) __TYPE = "CARTESIAN" oid = -1 while (True): # for every line of each I if l == None: break if l[0] == ".": break fields = l.split() fcpt = 0 while (fcpt < len(fields)): # for every field in if fields[fcpt] == "I": fcpt += 1 if oid != -1: break oid = int(fields[fcpt]) fcpt += 1 continue if fields[fcpt] == "TYPE": fcpt += 1 __TYPE = (fields[fcpt]) fcpt += 1 continue if fields[fcpt] == "ORIGIN": fcpt += 1 __origin = np.array(list(map(float, fields[fcpt:fcpt+3]))) fcpt += 3 continue if fields[fcpt] == "V1": fcpt += 1 __V1 = np.array(list(map(float, fields[fcpt:fcpt+3]))) fcpt += 3 continue if fields[fcpt] == "V2": fcpt += 1 __V2 = np.array(list(map(float, fields[fcpt:fcpt+3]))) fcpt += 3 continue if fields[fcpt] == "V3": fcpt += 1 __V3 = np.array(list(map(float, fields[fcpt:fcpt+3]))) fcpt += 3 continue print(fcpt) print(fields) raise else: l = self.ReadCleanLine() if l == None: break if l[0] == ".": break continue break # print(fields) self.FRAME[oid] = {"T": __TYPE, "O": __origin, "V1": __V1, "V2": __V2} #print("self.FRAME " ,self.FRAME) if l == None: break if l[0] == ".": break # print(self.FRAME) continue if ldata["KEYWORD"] == "AEL": Info('Reading Elements') cpt = 0 while (True): l = self.ReadCleanLine() if l == None: break if l[0] == ".": break fields = l.split() fcpt = 0 __I = -1 __FRAME = -1 __MAT = -1 __GROUP = -1 while (fcpt < len(fields)): if fields[fcpt] == "I": fcpt += 1 __I = int(fields[fcpt]) fcpt += 1 continue if fields[fcpt] == "FRAME": fcpt += 1 __FRAME = int(fields[fcpt]) fcpt += 1 continue if fields[fcpt] == "MAT": fcpt += 1 __MAT = int(fields[fcpt]) fcpt += 1 continue if fields[fcpt] == "GROUP": fcpt += 1 __GROUP = fields[fcpt] fcpt += 1 continue if fields[fcpt] == "DEGRE": fcpt += 1 __DEGRE = fields[fcpt] fcpt += 1 continue print(fields) raise self.AEL.append({'I': __I, "G": __GROUP, "M": __MAT, "F": __FRAME}) continue if ldata["KEYWORD"] == "MAI": Info('Reading Elements') #"I 1 N 55175 65855 57080 0 58679" cpt = 0 while (True): l = self.ReadCleanLine() if l == None: break if l[0] == ".": break fields = l.split() fcpt = 0 while (fcpt < len(fields)): if fields[fcpt] == "I": fcpt += 1 oid = int(fields[fcpt]) fcpt += 1 if fields[fcpt] == "ATT": fcpt += 1 __data = (fields[fcpt]) fcpt += 1 if fields[fcpt] == "ED.M": fcpt += 1 __data = (fields[fcpt]) fcpt += 1 if fields[fcpt] == "N": fcpt += 1 p2 = [] while (fcpt < len(fields)): p = [] while (fcpt < len(fields)): if int(fields[fcpt]) == 0: fcpt += 1 break p.append(int(fields[fcpt])) fcpt += 1 p2.append(p) # Info(p2) if len(p2) == 2: if len(p2[0]) == 3 and len(p2[1]) == 1: elements = res.GetElementsOfType(ED.Tetrahedron_4) elif len(p2[0]) == 4 and len(p2[1]) == 4: elements = res.GetElementsOfType(ED.Hexahedron_8) elif len(p2[0]) == 3 and len(p2[1]) == 3: elements = res.GetElementsOfType(ED.Wedge_6) else: raise (Exception("type of element no coded" + str(p2))) elif len(p2) == 1: if len(p2[0]) == 3: elements = res.GetElementsOfType(ED.Triangle_3) elif len(p2[0]) == 4: elements = res.GetElementsOfType(ED.Quadrangle_4) else: raise (Exception("type of element no coded" + str(p2))) else: raise (Exception("type of element no coded" + str(p2))) flist = [item for sublist in p2 for item in sublist] conn = GetInternalNumberFromOriginalid(flist) cid = elements.AddNewElement(conn, oid) filetointernalidElement[oid] = (elements, cid-1) continue Info("--------------- Error reading this line ------------------") Info(l) Info("----------------------------------------------------------") raise res.SetNodes(np.array([xs, ys, zs], dtype=MuscatFloat).T) res.originalIDNodes = np.array(originalsids, dtype=MuscatIndex) res.PrepareForOutput() self.filetointernalidElement = filetointernalidElement self.filetointernalid = filetointernalid # print(self.FRAME) # print(self.AEL) globalOffsets = res.ComputeGlobalOffset() if len(self.FRAME) > 0 and len(self.AEL) > 0: V1 = np.zeros((res.GetNumberOfElements(), 3)) V1[:, 0] = 1 V2 = np.zeros((res.GetNumberOfElements(), 3)) V2[:, 1] = 1 MAT = np.zeros((res.GetNumberOfElements(), 1))-1 for ael in self.AEL: if ael["I"] != -1: oid = ael["I"] oids = [globalOffsets[el.elementType] +cpt for el, cpt in [filetointernalidElement[oid]]] elif ael["G"] != -1: oids = res.GetElementsInTag("Group"+str(ael["G"])) else: raise if ael["F"] != -1: frame = self.FRAME[ael["F"]] (elements, cpt) = filetointernalidElement[oid] if frame["T"] != "CARTESIAN": raise if np.any(frame["O"]-[0, 0, 0]): raise #self.FRAME[oid] = {"T":__TYPE, "O":__origin, "V1":__V1, "V2":__V2 } # print(frame) V1[oids, :] = frame["V1"] V2[oids, :] = frame["V2"] elif ael["M"] != -1: MAT[oids] = ael["M"] res.elemFields["V1"] = V1 res.elemFields["V2"] = V2 res.elemFields["Mat"] = MAT # print(V1) # print(V2) return res
RegisterReaderClass(".dat", DatReader) RegisterReaderClass(".datt", DatReader)
[docs]def CheckIntegrity(): data = u""".INIT & .ASEF & MODE IMPRES 0 LECT 132 MOUCHARD 1 ECHO 1 .NOE 1 0 0 0 2 1.000000000E+01 0.000000000E+01 0.000000000E+00 3 0.000000000E+01 1.000000000E+01 0.000000000E+00 4 0.000000000E+01 0.000000000E+01 1.000000000E+00 .MAI I 1 N 1 2 3 0 4 .SEL GROUP 1 MAILLES NOM "SYS-1_CORPS_146" I 1 .SEL GROUP 2 MAILLES TOUT NOM "ALL_ELEMENTS" .SEL GROUP 3 NOEUD TOUT NOM "ALL_NODES" .CLM !*********** Fixed Supports *********** FIX NOEUD I 1 C 1 2 3 FIX NOEUD I 3 C 1 2 3 .FRAME I 1 TYPE CARTESIAN ORIGIN 0.000000 0.000000 0.000000 V1 0.886548 -0.462637 -0.000000 V2 0.000000 -0.000000 1.000000 I 2 TYPE CARTESIAN ORIGIN 0.000000 0.000000 0.000000 V1 0.959641 -0.281229 -0.000000 V2 0.000000 -0.000000 1.000000 .AEL I 1 FRAME 1 """ res = DatReader().Read(string=data) from Muscat.Helpers.IO.TemporaryDirectory import TemporaryDirectory tempdir = TemporaryDirectory.GetTempPath() f = open(tempdir+"SamcefReader_test_File.dat", "w") f.write(data) f.close() res = DatReader().Read(fileName=tempdir+"SamcefReader_test_File.dat") print(res) return 'ok'
if __name__ == '__main__': print(CheckIntegrity()) # pragma: no cover