I'm writing a Python parser for OpenFoam mesh files. When the mesh is big, I face performance issues.
Here is the format of the file describing the points:
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 2.2.0 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class vectorField;
location "constant/polyMesh";
object points;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
10
(
(2.14633 0.955 -0.627026)
(2.14633 1.005 -0.627026)
(4.0935 0.955 -0.389604)
(4.0935 1.005 -0.389604)
(0.199157 0.955 -0.864447)
(0.199157 1.005 -0.864447)
(3.075 1.005 0.562347)
(3.11114 1.005 0.558563)
(3.075 0.955 0.562347)
(3.11114 0.955 0.558563)
)
// ************************************************************************* //
The file describing the tetrahedron points:
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 2.2.0 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class faceList;
location "constant/polyMesh";
object faces;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
10
(
3(566037 390932 236201)
3(566037 146948 390932)
3(146948 236201 390932)
3(566037 236201 146948)
3(833456 434809 832768)
3(833456 832768 833463)
3(832768 434809 833463)
3(833456 833463 434809)
3(151487 504429 264888)
3(151487 264888 391870)
)
// ************************************************************************* //
Here is an example of boundary file:
/*--------------------------------*- C++ -*----------------------------------*\
| ========= | |
| \\ / F ield | OpenFOAM: The Open Source CFD Toolbox |
| \\ / O peration | Version: 2.2.0 |
| \\ / A nd | Web: www.OpenFOAM.org |
| \\/ M anipulation | |
\*---------------------------------------------------------------------------*/
FoamFile
{
version 2.0;
format ascii;
class polyBoundaryMesh;
location "constant/polyMesh";
object boundary;
}
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
2
(
object_surf
{
type wall;
physicalType wall;
nFaces 48738;
startFace 9010058;
}
vacuum_surf
{
type patch;
physicalType patch;
nFaces 167218;
startFace 9112924;
}
)
And the class I wrote to parse these files:
class ParsedMesh:
""" rep is the path to the directory containing the mesh files """
def __init__(self,rep):
def readFile(ficName):
""" readFile: read a file to parse. Returne a list of the lines of the file without "\n" and ";" character """
fic = open(os.path.join(rep,ficName),"r")
tmp = [ line.replace(';','').replace('\n','').strip() for line in fic ] # delete \n and ;
return [ line for line in tmp if line != '' ] # don't return the empty lines
def parseHeader(self):
res = {}
headerSection = False
### header parsing
for el in self.fileContent:
if el == "FoamFile":
headerSection = True
continue
if headerSection == True:
if el == "{":
continue
elif el == "}":
headerSection = False
return res
else:
tmpEl = el.replace('"','').split()
res[tmpEl[0]] = tmpEl[1]
continue
def parseBoundaryFile(self):
self.fileContent = readFile("boundary")
self.parsedMesh["boundary"]= {}
self.parsedMesh["boundary"]["sections"]= {}
# header
self.parsedMesh["boundary"]["header"] = parseHeader(self)
## body
boundarySection = False
boundaryInnerSection = False
for el in self.fileContent:
if el.split()[0] == "(": # beginning of the values section
boundarySection = True
continue
if el.split()[0] == ")": # end of the values section
boundarySection = False
break
if el == "{":
boundaryInnerSection = True
continue
if el == "}":
boundaryInnerSection = False
continue
# read values
if boundarySection == True:
if boundaryInnerSection == False:
boundName = el
self.parsedMesh["boundary"]["sections"][boundName] = {}
continue
else:
tmpEl = el.split()
self.parsedMesh["boundary"]["sections"][boundName][tmpEl[0]] = tmpEl[1]
continue
def parsePointsFile(self):
self.fileContent = readFile("points")
self.parsedMesh["points"]= {}
# header
self.parsedMesh["points"]["header"] = parseHeader(self)
## body
pointsSection = False
pointNumber = 0
self.parsedMesh["points"]["valuesList"] = []
for el in self.fileContent:
if el == "(": # beginning of the value section
pointsSection = True
continue
if el == ")": # end of the value section
pointsSection = False
break
# read the values
if pointsSection == True:
pointNumber += 1
self.parsedMesh["points"]["valuesList"].append(numpy.array([float(el2) for el2 in el[1:-1].split()]))
continue
def parseFacesFile(self):
self.fileContent = readFile("faces")
self.parsedMesh["faces"]= {}
# header
self.parsedMesh["faces"]["header"] = parseHeader(self)
## body
pointsSection = False
pointNumber = 0
self.parsedMesh["faces"]["valuesList"] = []
for el in self.fileContent:
if el == "(": # beginning of the value section
pointsSection = True
continue
if el == ")": # end of the value section
pointsSection = False
break
# read the values
if pointsSection == True:
pointNumber += 1
self.parsedMesh["faces"]["valuesList"].append([int(el2) for el2 in el[2:-1].split()])
continue
self.parsedMesh = {}
self.fileContent = []
parseBoundaryFile(self)
parsePointsFile(self)
parseFacesFile(self)
Any idea allowing a performance improvement is appreciated. Any other comment is also welcome (I'm a physicist using Python, so probably making a lot of obvious mistakes).