|
[Sponsors] |
Parse OpenFoam polyMesh in binary stream format |
![]() |
|
LinkBack | Thread Tools | Search this Thread | Display Modes |
![]() |
![]() |
#1 |
New Member
Daniel Dumitrascu
Join Date: Mar 2018
Posts: 2
Rep Power: 0 ![]() |
Hi guys,
I'm working on a tool that needs to parse the OpenFoam polyMesh files (points, faces, boundary). At this moment the tool can only parse the ASCII format of the polyMesh files and what I will need to add is the support for binary as well. Unfortunately, I don't know how to interpret the binary stream format. Is there any documentation on how OpenFoam parses these binary files ? Or, can anyone direct me on the OpenFoam code that handles polyMesh binary stream ? Any help is greatly appreciated. Thank you in advance, Daniel |
|
![]() |
![]() |
![]() |
![]() |
#2 |
New Member
Daniel Dumitrascu
Join Date: Mar 2018
Posts: 2
Rep Power: 0 ![]() |
After a little research I've managed to parse all 3 binary files.
boundary file was the easiest because even if the format from the header said that the file is in binary mode that was not the case for me. The file was in plain text (ASCII) so the parsing was easy to make. points file was a little harder to parse because even if the header was in ASCII, the data itself was stored in binary. If you look at the ASCII format for the points file from a polyMesh you will see that we have the number of points and then the points represented as below: 1681139 ( (-0.03975 0.0026372 -0.00919138) (-0.03975 0.00280753 -0.00910861) (-0.03975 0.00297785 -0.00902584) (-0.03975 0.00314818 -0.00894307) (-0.03975 0.00331851 -0.0088603) (-0.03975 0.00348883 -0.00877753) . . . In binary, the points are represented one after another so everything you need to do is to read chunks of 3 doubles till to reach the end. And that's it for the points. The faces file was a little bit trickier. In ASCII the data is represented as below: 4789790 ( 4(702 982 3040 1080) 4(19 1080 3040 346) 4(1 346 3040 982) 4(0 1 982 702) 4(0 702 1080 19) 4(0 19 346 1) . . . You have the number of faces (4789790 in this example) then, in front of every face the number of integers (4 in this example) forming the actual face, and the data for that face. In binary, you have the header which is in ASCII and then 2 vectors, one after another. The first one represents indexes for the data stored in the second vector. Why indexes? Well, because the faces don't have a constant number of integers (like in my example 4). You can find faces with 4, 5 or 6 integers and without the indexes telling you the start and end you wouldn't know how to read the data from the second vector. By the way, the indexes and the actual data are both integers. I've spend some time finding this information, hope this will help anyone who is trying to work with polyMesh files in binary format. |
|
![]() |
![]() |
![]() |
![]() |
#3 |
Member
Bob Tipton
Join Date: Apr 2020
Posts: 34
Rep Power: 6 ![]() |
There are few details that were unexpected.
Despite the file's ascii headers - they are binary files and need to be opened using ifstream::binary. Otherwise erroneous EOFs occur. The vector sizes are ascii numbers followed by the same ()s as in the ascii format. Only the data within in the ()s is actually binary. This requires some odd trickery of when to read as ascii ints and when to read binary ints. It's not obvious. |
|
![]() |
![]() |
![]() |
![]() |
#4 |
Member
Bob Tipton
Join Date: Apr 2020
Posts: 34
Rep Power: 6 ![]() |
Since SnappyHexMesh is problematic and other open source options have gone commercial while their open source versions have not been updated in some time AND I really needed a good mesher - I've been working on one.
Part of that is getting a very good understanding of the polymesh file format. The official documentation is correct, but sparse. I hope this helps. A face on a cell may be subdivided into multiple, coplanar faces - this is implied in the documentation but not clearly stated. This is required so that the size of cells may step up and down as needed. If a hexCell has one face divided into 4 equal parts the adjacent faces must have vertices inserted - to form irregular pentagons - so that the cell is topologically closed. As a result, a cell may have any number of faces and a face may have any number of vertices. The number of faces in the "faces" file is actually nFaces+1 and the last entry is the number of points in the "vertices" int the vertex list section of the "faces" file. This is redundant, nonobvious and I assume it's there so that there is a terminal entry to compute the number of vertices in the face. This was found by dumping existing files. Output follows "Cells and faces match: false faceIndices.size():22429 ownerCells.size():22428" This discrepancy is required to successfully read the file. The files natural language is FORTRAN or C, not C++. I was never able to write a file successfully using C++ iostreams, but FILE IO works great. ints are signed 32 bit (int32_t) There are separate lists in the faces file, face indices and vert indices, which are both contained by "()"s The format is designed to use fread/frwite(entireBuffer, elementSize, numberOfEntries) as a single call. It can be done element at time, but that's slower with no benefits. The owner and neighbor files are the owner cell index and neighbor cell index for each face in the faces file. Shared faces MUST be sorted by owner cell index, then neighbor cell index. 1,2,3,4 0 1 5,6,7,8 0 4 9,10,11,12 0 6 13,14,15,16 1 2 17,18,19,20 1 3 . . . The shared faces MUST COME First in the faces file, with boundary and wall faces coming afterwards. It's probably LEGAL to violate this, but everything is simpler if you follow this rule. All faces connected to a single cell come LAST. This means the neighbour file can be truncated to the number of shared faces. Otherwise, it requires "-1"s to indicate the boundary faces. After all that - you can read and write polymesh files. Last edited by Bob Tipton; May 7, 2024 at 22:09. Reason: typos |
|
![]() |
![]() |
![]() |
![]() |
#5 | |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,714
Rep Power: 40 ![]() ![]() |
Only true if compiled with WM_LABEL_SIZE 32.
Quote:
Filling boundary faces with -1 is really, really ancient. |
||
![]() |
![]() |
![]() |
![]() |
#6 | |
Senior Member
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,714
Rep Power: 40 ![]() ![]() |
Quote:
To avoid numerous small allocations, the faces are frequently sorted in a CompactListList format. The indices of these are begin/end offsets so they always start with 0 and thus are always nFaces+1 length, except will be zero-length for nFaces=0. The initial zero is included in the indices since this makes walking the offset ranges easier without special treatment for the 0th element. |
||
![]() |
![]() |
![]() |
![]() |
#7 |
Member
Bob Tipton
Join Date: Apr 2020
Posts: 34
Rep Power: 6 ![]() |
Thank you for the clarifications!
Regarding "ancient". This has been a major barrier to understanding the Openfoam tool set. Much of the documentation is "ancient" but has not been annotated with terms like "deprecated." There is still documentation and comments in discussion boards about using "-1." |
|
![]() |
![]() |
![]() |
Tags |
ascii, binary, parse, polymesh, stream |
|
|
![]() |
||||
Thread | Thread Starter | Forum | Replies | Last Post |
[OpenFOAM] Using ASCII rather than binary VTK format because floatScalar and/or label are .... | quarkz | ParaView | 0 | November 22, 2017 20:58 |
[snappyHexMesh] How to define to right point for locationInMesh | Mirage12 | OpenFOAM Meshing & Mesh Conversion | 7 | March 13, 2016 14:07 |
[General] A "clean" solution to export binary ensight gold format from Fortran to Paraview? | flotus1 | ParaView | 1 | June 23, 2015 11:59 |
Cross-compiling OpenFOAM 1.7.0 on Linux for Windows 32 and 64bits with Mingw-w64 | wyldckat | OpenFOAM Announcements from Other Sources | 3 | September 8, 2010 06:25 |
Sliding mesh error | Karl Kevala | FLUENT | 4 | February 21, 2001 15:52 |