CFD Online Logo CFD Online URL
www.cfd-online.com
[Sponsors]
Home > Forums > Software User Forums > OpenFOAM > OpenFOAM Programming & Development

Parse OpenFoam polyMesh in binary stream format

Register Blogs Community New Posts Updated Threads Search

Reply
 
LinkBack Thread Tools Search this Thread Display Modes
Old   March 6, 2018, 06:13
Default Parse OpenFoam polyMesh in binary stream format
  #1
New Member
 
Daniel Dumitrascu
Join Date: Mar 2018
Posts: 2
Rep Power: 0
Daniel1966 is on a distinguished road
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
Daniel1966 is offline   Reply With Quote

Old   March 22, 2018, 06:12
Default Found the way to parse the binary files in polyMesh
  #2
New Member
 
Daniel Dumitrascu
Join Date: Mar 2018
Posts: 2
Rep Power: 0
Daniel1966 is on a distinguished road
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.
Daniel1966 is offline   Reply With Quote

Old   September 24, 2020, 10:12
Default More info
  #3
Member
 
Bob Tipton
Join Date: Apr 2020
Posts: 38
Rep Power: 7
Bob Tipton is on a distinguished road
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.
Bob Tipton is offline   Reply With Quote

Old   May 7, 2024, 23:07
Default Undocumented details of OF polymesh format
  #4
Member
 
Bob Tipton
Join Date: Apr 2020
Posts: 38
Rep Power: 7
Bob Tipton is on a distinguished road
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 23:09. Reason: typos
Bob Tipton is offline   Reply With Quote

Old   May 8, 2024, 09:48
Default
  #5
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Bob Tipton View Post
ints are signed 32 bit (int32_t)
Only true if compiled with WM_LABEL_SIZE 32.


Quote:
Originally Posted by Bob Tipton View Post
The shared faces MUST COME First in the faces file, with boundary and wall faces coming afterwards. It's probably LEGAL to violate this,
The internal faces must come first, no violations allowed.



Quote:
Originally Posted by Bob Tipton View Post
This means the neighbour file can be truncated to the number of shared faces. Otherwise, it requires "-1"s to indicate the boundary faces.
Filling boundary faces with -1 is really, really ancient.
olesen is offline   Reply With Quote

Old   May 8, 2024, 09:55
Default
  #6
Senior Member
 
Mark Olesen
Join Date: Mar 2009
Location: https://olesenm.github.io/
Posts: 1,715
Rep Power: 40
olesen has a spectacular aura aboutolesen has a spectacular aura about
Quote:
Originally Posted by Bob Tipton View Post
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.

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.
olesen is offline   Reply With Quote

Old   May 9, 2024, 03:06
Default
  #7
Member
 
Bob Tipton
Join Date: Apr 2020
Posts: 38
Rep Power: 7
Bob Tipton is on a distinguished road
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."
Bob Tipton is offline   Reply With Quote

Reply

Tags
ascii, binary, parse, polymesh, stream


Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are Off
Pingbacks are On
Refbacks are On


Similar Threads
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 21:58
[snappyHexMesh] How to define to right point for locationInMesh Mirage12 OpenFOAM Meshing & Mesh Conversion 7 March 13, 2016 15:07
[General] A "clean" solution to export binary ensight gold format from Fortran to Paraview? flotus1 ParaView 1 June 23, 2015 12: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 07:25
Sliding mesh error Karl Kevala FLUENT 4 February 21, 2001 16:52


All times are GMT -4. The time now is 15:57.