Lightweight library to parse OpenFOAM files using Numpy (Ofpp Fork)
Project description
Openfoamparser
This is a simple Python library for parsing result or mesh files in OpenFOAM output files to Numpy arrays. Both ascii and binary format are supported.
Installation
Install with pip:
pip install openfoamparser
or install with setup.py by:
python setup.py install
This package requires numpy.
APIs
parse field data
- parse_internal_field(fn): parse internal field data from file fn, and return field data as numpy.array
- parse_boundary_field(fn): parse boundary field data from file fn, return boundary dictionary with boundary name as keys and Numpy.array as values.
- parse_field_all(fn): parse internal field data and boundary field data from file fn.
parse mesh
Class FoamMesh can parse mesh data (in ascii or binary format) and provide inquiry.
instantiation
- FoamMesh(path): initialization of class, read and parse mesh data (points, boundary, owner, neighbour, faces) from path/constant/polyMesh
instance variables
- points: Numpy.array, coordinates of points, in order of point id, read from mesh file points
- owner: a list, the owner cell id of each face, in order of face id, read from mesh file owner
- neighbour: a list, the neighbour cell id of each face, read from mesh file neighbour. For faces on boudary, their neighbours are boundary's id.
- faces: list of list, the ids of points composed the face, in order of face id, read from mesh file faces
- boundary: dictionary, with key of boundary name, value of a namedtuple,
namedtuple('Boundary', 'type, num, start, id')
, in which num is face numer, start is the id of start face, id is the boundary id, equals to-10 - index
. - num_point: points number
- num_face: face number
- num_inner_face: inner face number
- num_cell: cell number
- cell_centres: Numpy.array, cell centre coordinates, read from field file, default is None
- cell_volumes: Numpy.array, cell volumes, read from field file, None for default
- face_areas: Numpy.array, face areas, read from field file, None for default
- cell_neighours: list of list, cell neibour cells' id, in order of cell id
- cell_faces: list of list, cell's face id, in order of cell id
class methods
- parse_points_content(content): parse points data from mesh file's content, in binary mode
- parse_owner_neighbour_content(content): parse owner or neighbour data from mesh file's content, in binary mode
- parse_faces_content(content): parse faces data from mesh file's content, in binary mode
- parse_boundary_content(content): parse boundary data from mesh file's content, in binary mode
mesh inquiry interface
- cell_neighbour_cells(i): return cell neighbours' id of cell i, in list
- boundary_cells(bd): return a generator of cell's id adjacent to boundary bd
- is_cell_on_boundary(i, bd): check if cell i is on boundary bd. if bd is None, check all boundaries.
- is_face_on_boundary(i, bd): check if face i is on boundary bd. if bd is None, check all boundaries.
Usage
import Ofpp
V = Ofpp.parse_internal_field('0/V')
wb01 = Ofpp.parse_boundary_field('0.1/alpha.water')
U02,Ub02 = Ofpp.parse_field_all('0.2/U')
mesh = Ofpp.FoamMesh('.')
wall_cells = list(mesh.boundary_cells(b'fixedWall'))
cell_neighbour_5 = mesh.cell_neighbour_cells(5)
Tutorial
prepare data of OpenFOAM
We use $FOAM_TUTORIALS/multiphase/interFoam/laminar/damBreak/damBreak for the demo.
➜ cp $FOAM_TUTORIALS/multiphase/interFoam/laminar/damBreak/damBreak .
➜ cd damBreak
➜ ./Allrun
➜ ls
0 0.1 0.2 0.3 0.4 0.5 0.6 0.7 0.8 0.9 1 Allrun log
0.05 0.15 0.25 0.35 0.45 0.55 0.65 0.75 0.85 0.95 Allclean constant system
➜ ls 0.6
alphaPhi0.water alpha.water p phi p_rgh U uniform
We use postProcess to generate cell volume data, which is written to file '0/V'
➜ postProcess -func 'writeCellVolumes' -time 0
➜ ls 0
alpha.water alpha.water.orig p_rgh U V
Use Ofpp to process data
Firstly, use function parse_internal_field
to parse '0/V' and get cell volume data,
>>> import Ofpp
>>> V=Ofpp.parse_internal_field('0/V')
>>> V.shape
(2268,)
>>> sum(V)
0.0049626061800001099
>>> max(V)
2.6281599999999998e-06
>>> min(V)
1.11212e-06
>>>
Parse alpha.water to get water's volume fraction,
>>> W0=Ofpp.parse_internal_field('0/alpha.water')
>>> W0.shape
(2268,)
>>> sum(W0*V)
0.00064609979999999856
>>> W01=Ofpp.parse_internal_field('0.1/alpha.water')
>>> sum(W01*V)
0.00064609986628872621
>>> max(W0)
1.0
>>>
Parse alpha.water of all time steps, and calculate water volume of each time to check mass ballance:
>>> import numpy as np
>>> Wa=[]
>>> for t in np.arange(0, 1.01, 0.05):
... Wa.append(Ofpp.parse_internal_field('%.4g/alpha.water'%t))
>>> ["{:.5g}".format(sum(x*V)) for x in Wa]
['0.0006461', '0.0006461', '0.0006461', '0.0006461', '0.0006461', '0.0006461', '0.0006461', '0.00064307', '0.00064047', '0.00063953', '0.00063297', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171', '0.00063171']
>>> import matplotlib.pyplot as pl
>>> pl.plot(np.arange(0, 1.01, 0.05), [sum(x*V) for x in Wa], 's-')
Parse velocity field, which is a vector field. And calculate the velocity magnitude,
>>> U01=Ofpp.parse_internal_field('0.1/U')
>>> U01.shape
(2268, 3)
>>> U01[50]
array([ 0.280417 , -0.0783402, 0. ])
>>> v01=(U01[:,0]**2+U01[:,1]**2+U01[:,2]**2)**0.5
>>> v01[50]
0.29115439344966104
Noticing that some fields are uniform, eg. initial velocity, whose data is a vector,
>>> U0=Ofpp.parse_internal_field('0/U')
>>> U0
array([ 0., 0., 0.])
>>>
boundary data
Boundary data parsed by Ofpp is a dictionary because there are usually more than one boundary entities. Its keys are boundary names and values are also dictionaries.
>>> b01=Ofpp.parse_boundary_field('0.1/alpha.water')
>>> b01.keys()
dict_keys([b'rightWall', b'atmosphere', b'leftWall', b'lowerWall', b'defaultFaces'])
>>> b01[b'atmosphere'].keys()
dict_keys([b'inletValue', b'value'])
>>> b01[b'atmosphere'][b'inletValue']
0.0
>>> b01[b'atmosphere'][b'value'].shape
(46,)
>>> b01[b'atmosphere'][b'value']
array([ 0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 0.00000000e+00,
0.00000000e+00, 0.00000000e+00, 6.48450000e-54,
1.03531000e-52, 3.02802000e-53, 1.67528000e-53,
9.36177000e-54, 4.89156000e-54, 2.18620000e-54,
5.33282000e-55, 8.91129000e-56, 1.13156000e-56,
1.13522000e-57, 9.31454000e-59, 6.39173000e-60,
3.72975000e-61, 1.85390000e-62, 8.04808000e-64,
3.10349000e-65, 1.01620000e-66, 2.83696000e-68,
6.78134000e-70, 1.35776000e-71, 2.23345000e-73,
2.92040000e-75, 2.88435000e-77, 1.93630000e-79,
5.49169000e-82])
>>>
mesh
Create a FoamMesh object and read mesh file.
>>> mesh = Ofpp.FoamMesh('.')
>>> mesh.num_face
9176
>>> mesh.num_inner_face
4432
>>> mesh.num_cell
2267
>>> mesh.num_point
4746
>>> mesh.boundary
{b'lowerWall': Boundary(type=b'wall', num=62, start=4532, id=-12),
b'rightWall': Boundary(type=b'wall', num=50, start=4482, id=-11),
b'atmosphere': Boundary(type=b'patch', num=46, start=4594, id=-13),
b'defaultFaces': Boundary(type=b'empty', num=4536, start=4640, id=-14),
b'leftWall': Boundary(type=b'wall', num=50, start=4432, id=-10)}
>>>
Read outside data for cell volumes, cell centers
>>> mesh.read_cell_volumes('0/V')
>>> mesh.read_cell_centres('0/C')
Mesh inquiry:
>>> mesh.cell_neighbour_cells(300)
[281, 299, 301, 319, -14, -14]
>>> mesh.cell_faces[134]
[263, 264, 4797, 4981, 219, 261]
>>> cell_to_wall=list(mesh.boundary_cells(b'leftWall'))
>>> len(cell_to_wall)
50
>>> mesh.is_cell_on_boundary(545)
True
>>> mesh.is_cell_on_boundary(545, b'atmosphere')
False
>>> mesh.is_face_on_boundary(334, b'leftWall')
False
Authors
XU Xianghua
Jan Drees
Timothy-Edward-Kendon
YuyangL
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
File details
Details for the file openfoamparser-0.13.tar.gz
.
File metadata
- Download URL: openfoamparser-0.13.tar.gz
- Upload date:
- Size: 14.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/1.13.0 pkginfo/1.5.0.1 requests/2.22.0 setuptools/41.2.0 requests-toolbelt/0.8.0 tqdm/4.35.0 CPython/3.7.4
File hashes
Algorithm | Hash digest | |
---|---|---|
SHA256 | def63c3fe2e95dd32eb35358c0ef0c09eed4fe044032acab36b44445aefcd8f0 |
|
MD5 | 989e21b5e18e9570d114cd171adbc984 |
|
BLAKE2b-256 | fd83dfbdf81035f1f8c4337b5cf28d1b47d50e0286c5c8b167f45f7059923f7f |