# -*- 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.
#
"""Inp file reader (Abaqus simulation file)
"""
import re
import numpy as np
import csv
from BasicTools.NumpyDefs import PBasicFloatType, PBasicIndexType
from BasicTools.Helpers.Timer import Timer
import BasicTools.Containers.ElementNames as EN
from BasicTools.Containers.Filters import ElementFilter
from BasicTools.IO.ReaderBase import ReaderBase
from BasicTools.IO.AbaqusTools import InpNameToBasicTools, permutation
KeywordToIgnore = ["INITIAL CONDITIONS",
"AMPLITUDE",
"EXPANSION",
"DISTRIBUTION TABLE",
"COUPLING",
"SOLID SECTION",
"CONNECTOR SECTION",
"SURFACE",
"SURFACE INTERACTION",
"FRICTION",
"CONTACT PAIR",
"CLEARANCE",
"PARAMETER",
"PART",
"END PART",
"ASSEMBLY",
"INSTANCE",
"END INSTANCE",
"END ASSEMBLY",
"PREPRINT",
"Step",
"Static",
"SOLVER",
"Output",
"NODE OUTPUT",
"Element Output",
"LOAD CASE",
"Boundary",
"End Step",
"SOLVER CONTROLS",
]
intFilter = re.compile("^[0-9]*$")
[docs]def JoinInp(filename):
fII = open("join_"+filename,"w")
def copyContent(filename):
for l in open(filename,"r"):
if len(l) >=8 and l[0:8] == "*INCLUDE":
copyContent( l.split("=")[1].strip())
pass
else:
fII.write(l)
copyContent(filename)
[docs]def SplitInp(filename):
import os
f = InpReader()
f.SetFileName(fileName= filename)
fII = open("split_"+filename,"w")
f.StartReading()
pairs = {"PART":"*END PART",
"INSTANCE":"*END INSTANCE",
"STEP":"*END STEP",
"Step":"*End Step",
"ASSEMBLY":"*END ASSEMBLY",}
def WriteOnFile(inputFile, outputFile, waitFor="*", pwd="./"):
print("working on " , " ", pwd)
if pwd != "./" and waitFor != "*":
os.mkdir(pwd)
keywordCpt = 0
l = inputFile.ReadCleanLine()
while(True):
if l is None:
return None
if l[0:len(waitFor)] == waitFor:
if waitFor == "*":
return l
else:
outputFile.write(l+"\n")
return inputFile.ReadCleanLine()
if l[0] == "*":
localData = LineToDic(l)
keyword = localData["KEYWORD"]+"_"+str(keywordCpt)
keywordCpt += 1
outputFile.write("*INCLUDE INPUT="+pwd+keyword+".partial\n")
kf = open(pwd+keyword+".partial","w")
kf.write(l+"\n")
if localData["KEYWORD"] in pairs:
waitForIn=pairs[localData["KEYWORD"]]
else:
waitForIn="*"
print("Creating file ", pwd+keyword+"/main.partial","w")
l = WriteOnFile(f, kf, waitFor=waitForIn, pwd=pwd+keyword+"/")
else:
outputFile.write(l+"\n")
l = inputFile.ReadCleanLine()
WriteOnFile(f,fII,waitFor="$$",pwd="./")
[docs]def LineToDic(text):
import csv
res = {}
for l in csv.reader([text], delimiter=',', quotechar='"'):
for f in l:
if len(f) == 0:
continue
if f[0] == "*":
res["KEYWORD"] = f[1:]
else:
if f.find("=") >-1:
s = f.split("=")
res[s[0].lstrip().rstrip().upper()] = s[1].lstrip().rstrip().lstrip('"').rstrip('"')
else:
res[f.lstrip().rstrip().upper()] = True
return res
[docs]def LineToList(text):
return list(csv.reader([text], delimiter=',', quotechar='"'))[0]
[docs]def LineToListNoQuote(text):
return [s.strip() for s in text.split(",")]
[docs]def DiscardTillNextStar(func):
while(True):
currentText = func()
if currentText is None:
break
if len(currentText) > 1 and currentText[0] == "*":
break
return currentText
[docs]def ReadInp(fileName=None,string=None,out=None,**kwargs):
"""Function API for reading an Abaqus inp 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 : UnstructuredMesh, optional
output unstructured mesh object containing reading result, by default None
Returns
-------
UnstructuredMesh
output unstructured mesh object containing reading result
"""
reader = InpReader()
reader.SetFileName(fileName)
reader.SetStringToRead(string)
return reader.Read(fileName=fileName, string=string,out=out,**kwargs)
[docs]class InpReader(ReaderBase):
"""Inp Reader class
"""
def __init__(self):
super(InpReader,self).__init__()
self.commentChar= "**"
self.readFormat = 'r'
[docs] def find(self,l,expr):
res = l.upper().find(expr.upper())
return res
[docs] def ReadCleanLine(self):
# in the inp abaqus the lines ending in ',' are splitted in multiple lines
res = super(InpReader,self).ReadCleanLine()
if res is None:
return res
if res[-1] == ",":
line = self.PeekLine()
if line[0] != "*":
return res + " "+ super(InpReader,self).ReadCleanLine()
return res
[docs] def Read(self,fileName=None,string=None, out=None):
"""Function that performs the reading of an Inp 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 : UnstructuredMesh, optional
output unstructured mesh object containing reading result, by default None
Returns
-------
UnstructuredMesh
output unstructured mesh object containing reading result
"""
import BasicTools.FE.ProblemData as ProblemData
from BasicTools.Linalg.Transform import Transform
import BasicTools.Containers.UnstructuredMesh 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.UnstructuredMesh()
else:
res = out
coefficient = 1.
meta = ProblemData.ProblemData()
fileToInternalIdPoint = {}
fileToInternalIdElement = {}
fileToGlobalElementId = {}
l = self.ReadCleanLine()
FENames = {}
while(True):
print(l)
if not l: break
localData = LineToDic(l)
if "KEYWORD" in localData and localData["KEYWORD"] in KeywordToIgnore:
print("Ignoring keyword: '" + str(localData["KEYWORD"]) +"' jumping to the next star" )
l = DiscardTillNextStar(self.ReadCleanLine )
continue
if self.find(l,"*HEADING")>-1:
l = self.ReadCleanLine()
HEADING = ""
while(True):
if l is None or l.find("*") > -1 or not l:
break
HEADING += str(l) + "\n"
l = self.ReadCleanLine()
continue
if self.find(l,"**LENGTH UNITS")>-1:
if l.find("mm")>-1:
coefficient = 0.001
l = self.ReadCleanLine()
continue
if self.find(l,"*NODE")>-1:
nodes= []
originalIds = []
cpt:PBasicIndexType = 0
l = self.ReadCleanLine()
dim:PBasicIndexType = 3
s = None
while(True):
if len(l) == 0 or l[0]=="*" or not l:
break
s = LineToListNoQuote(l)
oid = int(s[0])
fileToInternalIdPoint[oid] = cpt
nodes.append(list(map(float,s[1:])) )
originalIds.append(oid)
cpt += 1
l = self.ReadCleanLine()
if s is not None:
# we use the last point to detect the dimensionality of the mesh
dim = len(s)-1
res.nodes = np.array(nodes,dtype=PBasicFloatType)
res.nodes.shape = (cpt,dim)
res.originalIDNodes = np.array(originalIds,dtype=PBasicIndexType)
continue
if self.find(l,"*ELEMENT")>-1:
data = LineToDic(l)
elementType = data["TYPE"]
elementName = InpNameToBasicTools[elementType]
per = permutation.get(elementType,None)
l = self.ReadCleanLine()
elements = res.GetElementsOfType(elementName)
initialNumberOfElements = elements.GetNumberOfElements()
while(True):
if l is None or not l or l[0]== "*" :
break
s = LineToListNoQuote(l)
oid = int(s[0])
conn = [fileToInternalIdPoint[x] for x in map(int,s[1:]) ]
cid = elements.AddNewElement(conn,oid)-1
if elementName not in FENames:
FENames[elementName] = []
FENames[elementName].append(elementType)
fileToInternalIdElement[oid] = (elements,cid)
l = self.ReadCleanLine()
if per is not None:
elements.connectivity = elements.connectivity[:,per]
finalNumberOfElements = elements.GetNumberOfElements()
if "ELSET" in data:
elementSetName = data["ELSET"]
elements.GetTag(elementSetName).AddToTag(range(initialNumberOfElements,finalNumberOfElements))
elif elementType == "CONN3D2":
elements.GetTag("CONN3D2").AddToTag(range(initialNumberOfElements,finalNumberOfElements))
res.ComputeGlobalOffset()
continue
if self.find(l,"*NSET")>-1:
data = LineToDic(l)
nodeSetName = data['NSET']
l = self.ReadCleanLine()
nodesIds = []
if "GENERATE" in localData and localData["GENERATE"]:
d = LineToList(l)
d = (list(map(int,d) ))
nodesIds = range(d[0],d[1]+1,d[2])
tag = res.nodesTags.CreateTag(nodeSetName,False)
tagsIds = [fileToInternalIdPoint[x] for x in nodesIds if x in fileToInternalIdPoint ]
if len(tagsIds) != len(nodesIds):
print("Warning NSET GENERATE : not all the node ids generated are present in the mesh ")
tag.AddToTag(tagsIds)
l = self.ReadCleanLine()
continue
else:
while(True):
if l is None:
break
if l.find("*") > -1 or not l:
break
s = l.replace(',', '').split()
nodesIds.extend(map(int,s))
l = self.ReadCleanLine()
continue
tag = res.nodesTags.CreateTag(nodeSetName,False)
tag.AddToTag([fileToInternalIdPoint[x] for x in nodesIds ])
continue
if len(fileToGlobalElementId) == 0:
for (oi,(elements, id)) in fileToInternalIdElement.items():
fileToGlobalElementId[oi] = elements.globaloffset + id
if self.find(l,"*ELSET")>-1:
elementSetName = localData['ELSET']
l = self.ReadCleanLine()
ds = []
tagsNames = []
while(True):
if l is None or l.find("*") > -1 or not l:
if len(ds) > 0:
ids = [fileToGlobalElementId[dd] for dd in ds ]
res.AddElementsToTag(ids, elementSetName )
if len(tagsNames) >0 :
for elName, elData, elIds in ElementFilter(res, tags=tagsNames):
tag = elData.tags.CreateTag(elementSetName,False).AddToTag(elIds)
break
s = LineToListNoQuote(l)
# number are ids, str are names
ds.extend([int(ss) for ss in s if intFilter.match(ss) ] )
tagsNames.extend([ss for ss in s if not intFilter.match(ss) ] )
l = self.ReadCleanLine()
continue
continue
if self.find(l,"*DISTRIBUTION")>-1:
data = LineToDic(l)
location = data['LOCATION'] # "ELEMENT"
name = data['NAME'] # "ELEMENT"
table = data['TABLE'] # "ELEMENT"
if table == "DistributionTable_Orientation":
NumberOfData = 6
elif table == "DistributionTable_Density":
NumberOfData = 1
elif table == "DistributionTable_Elastic":
NumberOfData = 9
elif table == "DISTRIB_TABLE":
NumberOfData = 9
else:
raise Exception("Error! ")
data = np.zeros((res.GetNumberOfElements(),NumberOfData))
buffer = np.zeros(NumberOfData)
if location == "ELEMENT":
l = self.ReadCleanLine()
s = l.split(',')
if len(s[0]) == 0:
#default values
s = list(map(float,s[1:]))
if len(s) < NumberOfData:
# multiline data
s.extend(map(float,self.ReadCleanLine().split(',')) )
s = np.array(s)
for i,v in enumerate(s):
data[:,i] = v
l = self.ReadCleanLine()
while(True):
if l is None or l.find("*") > -1 or not l:
break
s = l.split(",")
elementTagName = s[0].split(".")[-1]
buffer[0:len(s)-1] = np.array(s[1:], dtype = PBasicFloatType )
if len(s) < NumberOfData:
# multiline data
buffer[len(s)-1:] = np.fromstring(self.ReadCleanLine(), dtype =PBasicFloatType, sep="," )
#s.extend( )
#map(float,self.ReadCleanLine().replace(',', ' ').split()) )
#else :
# s = np.array(s[1:], dtype = PBasicFloatType ) list(map(float,s[1:]))
#s= np.array(s)
for elementName, elementData, elementsIds in ElementFilter(res ,tag=elementTagName):
data[elementsIds+elementData.globaloffset,:] = buffer
l = self.ReadCleanLine()
if table == "DistributionTable_Orientation":
res.elemFields["V1"] = data[:,0:3]
res.elemFields["V2"] = data[:,3:]
elif table == "DistributionTable_Density":
res.elemFields["density"] = data
elif table == "DistributionTable_Elastic":
res.elemFields["E"] = data
res.elemFields["E1"] = data[:,0]
res.elemFields["E2"] = data[:,1]
res.elemFields["E3"] = data[:,2]
res.elemFields["Nu12"] = data[:,3]
res.elemFields["Nu13"] = data[:,4]
res.elemFields["Nu23"] = data[:,5]
res.elemFields["G12"] = data[:,6]
res.elemFields["G13"] = data[:,7]
res.elemFields["G23"] = data[:,8]
continue
if self.find(l,"*MATERIAL") > -1:
data = LineToDic(l)
name = data["NAME"]
mat = ProblemData.Material()
while(True):
l = self.ReadCleanLine()
if l is None:
break
data = LineToDic(l)
t = data["KEYWORD"]
if t not in ["ELASTIC","DENSITY","EXPANSION","ELASTIC","DISTRIBUTION"] :
break
if t == "DISTRIBUTION":
print("Ignoring DISTRIBUTION")
l = DiscardTillNextStar(self.ReadCleanLine )
break
if t == "EXPANSION":
if "ZERO" in data:
mat.AddProperty(t,"ZERO",data["ZERO"])
if "TYPE" in data:
st = data["TYPE"]
else:
st = None
l = self.ReadCleanLine()
s = list(l.strip('\n').strip().split() )
mat.AddProperty(t,st,s)
meta.materials[name] = mat
continue
if self.find(l,"*ORIENTATION")>-1:
data = LineToDic(l)
orient = Transform()
name = data["NAME"]
orient.system = data["SYSTEM"]
if orient.system != "RECTANGULAR":
s = list(map(float, self.ReadCleanLine().replace(","," ").split() ))
orient.SetFirst(s[0:3])
orient.SetSecond(s[3:6])
if len(s) >= 9:
orient.SetOffset(s[6:9])
meta.orientations[name] = orient
l = DiscardTillNextStar(self.ReadCleanLine )
continue
if self.find(l,"*SURFACE")>-1:
data = LineToDic(l)
name = data["NAME"]
if data["TYPE"] == "ELEMENT":
l = self.ReadCleanLine()
while(True):
if l is None:
break
if l.find("*") > -1 or not l:
break
s = l.split(",")
originalElemNumber = int(s[0])
faceNumber = int(s[1].lstrip().rstrip()[-1])-1
elements,cid = fileToInternalIdElement[originalElemNumber][0]
connectivity = elements.connectivity[cid,:]
faceType, faceLocalConnectivity = EN.faces[elements.elementType][faceNumber]
faceConnectivity = connectivity[faceLocalConnectivity]
elements = res.GetElementsOfType(faceType)
cid = elements.AddNewElement(faceConnectivity,-1)
if faceType not in FENames:
FENames[faceType] = []
FENames[faceType].append("NA")
elements.GetTag(name).AddToTag(cid-1)
l = self.ReadCleanLine()
continue
res.ComputeGlobalOffset()
continue
else:
raise Exception("NOT IMPLEMENTED sorry")
#*COUPLING, CONSTRAINT NAME="Coupling-1", REF NODE=239100, SURFACE="Rigid Connection1-1"
#*KINEMATIC
#1, 6
if localData["KEYWORD"] == "STEP":
data = LineToDic(l)
name = data["NAME"]
l = self.ReadCleanLine()
cs = ProblemData.StudyCase()
while(True):
data = LineToDic(l)
if "KEYWORD" in data and data["KEYWORD"] == "END STEP":
l = self.ReadCleanLine()
break
if "KEYWORD" in data and data["KEYWORD"] == "STATIC":
cs.type = "STATIC"
l = DiscardTillNextStar(self.ReadCleanLine)
continue
print(l)
print(localData)
print(("line starting with <<"+l[:20]+">> not considered in the reader"))
l = self.ReadCleanLine()
raise Exception("Error reading file")
self.EndReading()
res.originalIDNodes = np.squeeze(res.originalIDNodes)
feNames = []
for elementName in res.elements:
feNames.extend(FENames[elementName])
res.elemFields["FE Names"] = np.array(feNames,dtype=np.str_)
res.PrepareForOutput()
self.meta = meta
return res
from BasicTools.IO.IOFactory import RegisterReaderClass
RegisterReaderClass(".inp",InpReader)
[docs]def CheckIntegrity():
res1 = LineToDic('*NSET, NSET="Fixed Displacement1", KEY2=5')
if res1['KEY2'] != '5':
return "not ok"
data = u"""** -------------------------------------------------------
** ABAQUS input file
** File exported by VISUAL-ENVIRONMENT : Version10.7
** on 2016-4-8, at 10Hr:44min
** -------------------------------------------------------
**LENGTH UNITS: mm
*NODE
1, 3.0310898125000696, 1.7500003247594429, 0.00059999999999149622
2, 2.9785080000000002, 0.87500000000000011, 0.75012199999999996
3, 3.1961719999999998, 1.0006690000000003, 1.5926899999999999
4, 2.2943020000000001, 0.4799735, 1.4870170000000003
5, 2.9259249999999999, 0., 1.4996439999999893
6, 2.7781790000000002, 0.78753359999999994, 2.3200409999999998
*ELEMENT, TYPE=C3D4, ELSET=AM1_labo
1, 1, 2, 3, 4
2, 3, 5, 6, 4"""
res = ReadInp(string=data)
from BasicTools.Helpers.Tests import TestTempDir
tempdir = TestTempDir.GetTempPath()
f =open(tempdir+"test.inp","w")
f.write(data)
f.close()
res = ReadInp(fileName=tempdir+"test.inp")
print(res)
return 'ok'
if __name__ == '__main__':
print(CheckIntegrity())# pragma: no cover