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).