Plot3D Data FormatΒΆ
Data format for plot3D comes from this 1990s manual pdf
Plot3D is a simple way to construct a structured grid using 4 points to define a cell in 2D and 8 points for 3D.
Plot3D files are organized as follows
1 8 # Number of blocks
2 5 5 5 # Block 1 is shaped 5x5x5 in i,j,k this is 125 nodes
3 5 5 5 # Block 2 shape
4 5 5 5
5 5 5 5
6 5 5 5
7 5 5 5
8 5 5 5
9 5 5 5
10 1.08569236018e-07 2.89960779720e-07 2.99150448968e-07 2.55513369907e-07 # First 125 values describe are X, next 25 are Y, last 25 are Z
11 2.12244548714e-07 1.01483086157e-07 2.67218012828e-07 2.71062573276e-07
12 2.24420893535e-07 1.78210401103e-07 7.47886754748e-08 1.93926065872e-07
13 1.84719158858e-07 1.38925249638e-07 1.00523800506e-07 1.71518139691e-08
14 9.37154616132e-08 9.36074304736e-08 5.80944219397e-08 2.00380892990e-08
15 -5.46866818496e-08 -1.24404013757e-08 1.15859071226e-08 -4.76059469623e-09
Knowing this, reading the files is fairly simple to do in python. The following code blocks demonstrate how to read a simple ASCII or binary file. Calling the function read_plot3D(filename:str, binary:bool=True,big_endian:bool=False)
1import numpy as np
2import os.path as osp
3import struct
4from typing import List
5from .block import Block
6
7def __read_plot3D_chunk_binary(f,IMAX:int,JMAX:int,KMAX:int, big_endian:bool=False):
8 """Reads and formats a binary chunk of data into a plot3D block
9
10 Args:
11 f (io): file handle
12 IMAX (int): maximum I index
13 JMAX (int): maximum J index
14 KMAX (int): maximum K index
15 big_endian (bool, Optional): Use big endian format for reading binary files. Defaults False.
16
17 Returns:
18 numpy.ndarray: Plot3D variable either X,Y, or Z
19 """
20 A = np.empty(shape=(IMAX, JMAX, KMAX))
21 for k in range(KMAX):
22 for j in range(JMAX):
23 for i in range(IMAX):
24 A[i,j,k] = struct.unpack(">f",f.read(4))[0] if big_endian else struct.unpack("f",f.read(4))[0]
25 return A
26
27def __read_plot3D_chunk_ASCII(tokenArray:List[str],offset:int,IMAX:int,JMAX:int,KMAX:int):
28 """Reads an ascii chunk of plot3D data into a block
29
30 Args:
31 tokenArray (List[str]): this is a list of strings separated by a space, new line character removed ["12","22", ... etc]
32 offset (int): how many entries to skip in the array based on block size (IMAX*JMAX*KMAX) of the previous block
33 IMAX (int): maximum I index
34 JMAX (int): maximum J index
35 KMAX (int): maximum K index
36
37 Returns:
38 numpy.ndarray: Plot3D variable either X,Y, or Z
39 """
40 '''Works for ASCII files
41 '''
42 A = np.empty(shape=(IMAX, JMAX, KMAX))
43 for k in range(KMAX):
44 for j in range(JMAX):
45 for i in range(IMAX):
46 A[i,j,k] = tokenArray[offset]
47 offset+=1
48
49 return A, offset
50
51def read_plot3D(filename:str, binary:bool=True,big_endian:bool=False):
52 """Reads a plot3d file and returns Blocks
53
54 Args:
55 filename (str): name of the file to read, .p3d, .xyz, .pdc, .plot3d?
56 binary (bool, optional): indicates if the file is binary. Defaults to True.
57 big_endian (bool, optional): use big endian format for reading binary files
58
59 Returns:
60 List[Block]: List of blocks insdie the plot3d file
61 """
62
63 blocks = list()
64 if osp.isfile(filename):
65 if binary:
66 with open(filename,'rb') as f:
67 nblocks = struct.unpack(">I",f.read(4))[0] if big_endian else struct.unpack("I",f.read(4))[0] # Read bytes
68 IMAX = list(); JMAX = list(); KMAX = list()
69 for b in range(nblocks):
70 if big_endian:
71 IMAX.append(struct.unpack(">I",f.read(4))[0]) # Read bytes
72 JMAX.append(struct.unpack(">I",f.read(4))[0]) # Read bytes
73 KMAX.append(struct.unpack(">I",f.read(4))[0]) # Read bytes
74 else:
75 IMAX.append(struct.unpack("I",f.read(4))[0]) # Read bytes
76 JMAX.append(struct.unpack("I",f.read(4))[0]) # Read bytes
77 KMAX.append(struct.unpack("I",f.read(4))[0]) # Read bytes
78
79 for b in range(nblocks):
80 X = __read_plot3D_chunk_binary(f,IMAX[b],JMAX[b],KMAX[b], big_endian)
81 Y = __read_plot3D_chunk_binary(f,IMAX[b],JMAX[b],KMAX[b], big_endian)
82 Z = __read_plot3D_chunk_binary(f,IMAX[b],JMAX[b],KMAX[b], big_endian)
83 b_temp = Block(X,Y,Z)
84 blocks.append(b_temp)
85 else:
86 with open(filename,'r') as f:
87 nblocks = int(f.readline())
88 IMAX = list(); JMAX = list(); KMAX = list()
89
90 for b in range(nblocks):
91 tokens = [int(w.replace('\n','')) for w in f.readline().split(' ') if w]
92 IMAX.append(tokens[0])
93 JMAX.append(tokens[1])
94 KMAX.append(tokens[2])
95
96 lines = [l.replace('\n','').split(' ') for l in f.readlines()] # Basically an array of strings representing numbers
97 lines = [item for sublist in lines for item in sublist] # Flatten list of lists https://stackabuse.com/python-how-to-flatten-list-of-lists/
98
99 tokenArray = [float(entry) for entry in lines if entry] # Convert everything to float
100 offset = 0
101 for b in range(nblocks):
102 X, offset = __read_plot3D_chunk_ASCII(tokenArray,offset,IMAX[b],JMAX[b],KMAX[b])
103 Y, offset = __read_plot3D_chunk_ASCII(tokenArray,offset,IMAX[b],JMAX[b],KMAX[b])
104 Z, offset = __read_plot3D_chunk_ASCII(tokenArray,offset,IMAX[b],JMAX[b],KMAX[b])
105 b_temp = Block(X,Y,Z)
106 blocks.append(b_temp)
107 return blocks