HDF5 Data Types

An HDF5 is a binary file, containing model and result data, in a Hierarchical Data Format.

In the database, the datasets are stored in a hierarchical structure, making it easy to add, remove, or update dataset in applications. The database supports high precision, compression, and unlimited amount of data. Its open format and multiple programming languages support make it ideal for FEA applications.

OptiStruct HDF5 output is available in a .h5 file format. This is different from the .hdf5 (old) file format, which contains only the result data.

Supported Output Requests

For details regarding supported outputs, refer to the .h5 file.

Data Types

The data type schema is used to define database structure and its datasets formats. The database has a tree structure with its nodes of datasets. Each dataset uses its path in the tree as its identifier and defines a structure data format. The schema is in XML and has elements like <typedef>, <group> and <dataset>. The following is a brief overview of the structure of HDF5 data in OptiStruct.


Figure 1. Structure of HDF5 data in OptiStruct

Supported Group Names

The data in an HDF5 file is hierarchically structured in the form of groups. The most basic form of data in the tree is called a dataset. The following tables summarize the currently supported groups and their relevant datasets.

OptiStruct INPUT Group

The following are the datasets within the COORDINATE_SYSTEM group.
Table 1. OPTISTRUCT/INPUT/COORDINATE_SYSTEM
Dataset Name Field Type Description
CORD1C CID integer Coordinate system identification number.
G1 integer Grid point IDs to define the coordinate system.
G2 integer
G3 integer
DOMAIN_ID integer Domain identifier
CORD1R CID integer Coordinate system identification number.
G1 integer Grid point IDs to define the coordinate system.
G2 integer
G3 integer
DOMAIN_ID integer Domain identifier
CORD1S CID integer Coordinate system identification number.
G1 integer Grid point IDs to define the coordinate system.
G2 integer
G3 integer
DOMAIN_ID integer Domain identifier
CORD2C CID integer Coordinate system identification number.
RID integer Reference coordinate system identification number.
A1 double Grid point IDs to define the coordinate system.
A2 double
A3 double
B1 double
B2 double
B3 double
C1 double
C2 double
C3 double
DOMAIN_ID integer Domain identifier
CORD2R CID integer Coordinate system identification number.
RID integer Reference coordinate system identification number.
A1 double Grid point IDs to define the coordinate system.
A2 double
A3 double
B1 double
B2 double
B3 double
C1 double
C2 double
C3 double
DOMAIN_ID integer Domain identifier
CORD2S CID integer Coordinate system identification.
RID integer Reference coordinate system identification.
A1 double Grid point IDs to define the coordinate system.
A2 double
A3 double
B1 double
B2 double
B3 double
C1 double
C2 double
C3 double
DOMAIN_ID integer Domain identifier
The following are the datasets within the ELEMENT group.
Table 2. OPTISTRUCT/INPUT/ELEMENT
Dataset Name Field Type Description
CBAR EID integer Element identification number.
PID integer Property identification number.
GA integer Grid point identification numbers of connection points.
GB integer
FLAG integer Orientation vector option
= 0
XYZ Basic
= 1
XYZ Global
= 2
Grid
X1 double Components of vector v, at end A, measured at end A, parallel to the components of the displacement coordinate system for GA, or the basic coordinate system, to determine (with the vector from end A to end B) the orientation of the element coordinate system for the BAR element.
X2 double
X3 double
G0 integer Grid point identification number to optionally supply X1, X2, X3.
PA integer Pin flag for bar end A.
PB integer Pin flag for bar end B.
W1A double Components of offset vectors wa and wb in displacement coordinate systems at points GA and GB, respectively, or in the element coordinate system.
W2A double
W3A double
W1B double
W2B double
W3B double
DOMAIN_ID integer Domain identifier
CBEAM EID integer Element identification number.
PID integer Property identification number.
GA integer Grid point identification numbers of connection points.
GB integer
SA integer Currently unused
SB integer
X double Components of the orientation vector (from X1, X2 and X3)
G0 integer Grid point identification number to optionally supply X1, X2, X3.
F integer Flag to indicate the existence of G0
-1
Implies that G0 is not used
0
Implies that G0 is activated
PA integer Pin flag for beam end A.
PB integer Pin flag for beam end B.
WA double Components of offset vectors, measured in the displacement coordinate systems at grid points A and B or in the element coordinate system, from the grid points to the end points of the axis of shear center.
WB double
DOMAIN_ID integer Domain identifier
CBUSH EID integer Element identification number.
PID integer Property identification number.
GA integer Grid point identification number of the first connection point.
GB integer Grid point identification number of the second connection point.
FLAG integer Orientation vector option:
= -1
CID
= 0
XYZ Basic
= 1
XYZ Global
= 1
Grid
X1 double Components of the orientation vector from GA in the displacement coordinate system of GA.
X2 double
X3 double
G0 integer Alternate method to supply orientation vector using grid point G0.
CID integer Element coordinate system identification number.
S double Location of spring-damper as a fraction along the line segment between GA and GB.
OCID integer Coordinate system identification for spring-damper offset.
S1 double Components of the spring-damper offset in the OCID coordinate system.
S2 double
S3 double
DOMAIN_ID integer Domain identifier
CELAS1 EID integer Element identification number.
PID integer Property entry identification number.
G1 double Geometric grid point or scalar point identification number.
G2 double
C1 double Component number in the displacement coordinate system specified by the CD entry of the GRID data.
C2 double
DOMAIN_ID integer Domain identifier
CELAS2 EID integer Unique element identification number.
K double Spring stiffness.
G1 double Geometric grid point or scalar point identification number.
G2 double
C1 double Component number in the displacement coordinate system specified by the CD entry of the GRID data.
C2 double
GE double Damping coefficient.
S double Stress coefficient.
DOMAIN_ID integer Domain identifier
CHEXA EID integer Element identification number.
PID integer Property identification number.
G integer Grid point identification numbers of connection points.
DOMAIN_ID integer Domain identifier
CPENTA EID integer Element identification number.
PID integer Property identification number.
G integer Grid point identification numbers of connection points.
DOMAIN_ID integer Domain identifier
CQUAD4 EID integer Element identification number.
PID integer Property identification number.
G integer Grid point identification numbers of connection points.
THETA double Material orientation angle in degrees.
ZOFFS double Offset from the plane defined by element grid points to the shell reference plane.
TFLAG integer Flag to indicate the existence of T.
-1
Implies that T is not specified.
Other values imply that T is specified.
T double Thickness of the element at the grid points.
MCID integer Material coordinate system identification number.
DOMAIN_ID integer Domain identifier
CQUAD8 EID integer Element identification number.
PID integer Property identification number.
G integer Grid point identification numbers of connection points.
THETA double Material orientation angle in degrees.
ZOFFS double Offset from the plane defined by element grid points to the shell reference plane.
TFLAG integer Flag to indicate the existence of T.
-1
Implies that T is not specified.
Other values imply that T is specified.
T double Thickness of the element at the grid points.
MCID integer Material coordinate system identification number.
DOMAIN_ID integer Domain identifier
CSHEAR EID integer Element identification number.
PID integer Property identification number.
G integer Grid point identification numbers of the connection points.
DOMAIN_ID integer Domain identifier
CTETRA EID integer Element identification number.
PID integer Property identification number.
G integer Connected grid points identification number.
DOMAIN_ID integer Domain identifier
CTRIA3 EID integer Element identification number.
PID integer Property identification number.
G integer Connected grid points identification number.
THETA double Material orientation angle in degrees.
ZOFFS double Offset from the plane defined by element grid points to the shell reference plane.
TFLAG integer Flag to indicate the existence of T.
-1
Implies that T is not specified.
Other values imply that T is specified.
T double Thickness of the element at the grid points.
MCID integer Material coordinate system identification number.
DOMAIN_ID integer Domain identifier
CTRIA6 EID integer Element identification number.
PID integer Property identification number.
G integer Connected grid points identification number.
THETA double Material orientation angle in degrees.
ZOFFS double Offset from the plane defined by element grid points to the shell reference plane.
TFLAG integer Flag to indicate the existence of T.
-1
Implies that T is not specified.
Other values imply that T is specified.
T double Thickness of the element at the grid points.
MCID integer Material coordinate system identification number.
DOMAIN_ID integer Domain identifier
The following are the datasets within the NODE group.
Table 3. OPTISTRUCT/INPUT/NODE
Dataset Name Field Type Description
GRID ID integer Grid identification number.
CP integer Coordinate system identification number.
X double Location of the grid point in coordinate system CP.
CD integer Coordinate system identification number in which the displacements, degrees-of-freedom, constraints, and solution vectors are defined at grid point.
PS integer Permanent single-point constraints associated with grid point.
SEIDE integer Currently unused
DOMAIN_ID integer Domain identifier
The following are the datasets within the MATERIAL group.
Table 4. OPTISTRUCT/INPUT/PROPERTY
Dataset Name Field Type Description
PBAR PID integer Property identification number.
MID double Material identification number.
A double Area of cross section.
I1 double Area moment of inertia in plane 1.
I2 double Area moment of inertia in plane 2.
NSM double Area product of inertia.
FE double Currently unused
C1 double Stress recovery coefficients.
C2 double
D1 double
D2 double
E1 double
E2 double
F1 double
F2 double
K1 double Area factor for shear.
K2 double
I12 double Area product of inertia.
DOMAIN_ID integer Domain identifier
PBARL PID integer Property identification number.
MID integer Material identification number.
GROUP character Indicates if an arbitrary beam section definition is to be used.
TYPE character Cross-section type.
INFO_POS integer  
INFO_LEN integer
DOMAIN_ID integer Domain identifier
PBEAM PID integer Property identification number.
MID integer Material identification number.
NSEGS integer Number of sections
CCF integer Currently unused
CWELD integer Currently unused
SECTION BEAM_SECTION This is a group of coefficients, which are used to define section property of beam.
K1 double Shear stiffness factor for plane 1.
K2 double Shear stiffness factor for plane 2.
S1 double Shear relief coefficients
S2 double
NSIA double Nonstructural mass moment of inertia per unit length about nonstructural mass center of gravity at end A.
NSIB double Nonstructural mass moment of inertia per unit length about nonstructural mass center of gravity at end B.
CWA double Warping coefficient for end A.
CWB double Warping coefficient for end B.
M1A double (y,z) coordinates of center of gravity of nonstructural mass at end A.
M2A double
M1B double (y,z) coordinates of center of gravity of nonstructural mass at end B.
M2B double
N1A double (y,z) coordinates of neutral axis at end A.
N2A double
N1B double (y,z) coordinates of neutral axis at end B.
N2B double
DOMAIN_ID integer Domain identifier
PBUSH PID integer Property identification number.
K double Nominal stiffness values in directions 1 through 6.
B double Nominal damping coefficients in directions 1 through 6.
GE double Nominal structural damping constants in directions 1 through 6.
SA double Stress recovery coefficient in the translational component.
ST double Stress recovery coefficient in the rotational component.
EA double Strain recovery coefficient in the translational component.
ET double Strain recovery coefficient in the rotational component.
M double Nominal mass values in directions 1 through 6.
DOMAIN_ID integer Domain identifier
PELAS PID integer Property identification number.
K double Elastic property value.
GE double Damping coefficient.
S double Stress coefficient.
DOMAIN_ID integer Domain identifier
PSHEAR PID integer Property identification number.
MID integer Material identification number.
T double Thickness of shear panel.
NSM double Nonstructural mass per unit area.
F1 double Effectiveness factor for extensional stiffness along edges 1-2 and 3-4.
F2 double Effectiveness factor for extensional stiffness along edges 2-3 and 1-4.
DOMAIN_ID integer Domain identifier
PSHELL PID integer Property identification number.
MID1 integer Material identification number for membrane.
T double Membrane thickness.
MID2 integer Material identification number for bending.
BK double Currently unused
MID3 integer Material identification number for transverse shear.
TS double Transverse shear thickness divided by the membrane thickness.
NSM double Nonstructural mass per unit area.
Z1 double Fiber distances for stress computation.
Z2 double
MID4 integer Material identification number for membrane-bending coupling.
DOMAIN_ID integer Domain identifier
PSOLID PID integer Property identification number.
MID integer Material identification number.
CORDM integer MID of material coordinate system.
IN integer Integration network
STRESS integer Location selection for stress output.
ISOP integer Integration schemes for elasto-plastic implicit nonlinear static analysis.
FCTN character Fluid element flag.
DOMAIN_ID integer Domain identifier

OptiStruct RESULTS Group

The following are the datasets within the ELEMENTAL/ELEMENT_FORCE group.
Table 5. OPTISTRUCT/RESULT/ELEMENTAL/ELEMENT_FORCE
Dataset Name Field Type Description
BAR EID integer Element identification number
BM1A double Bending moment end A plane 1
BM2A double Bending moment end A plane 2
BM1B double Bending moment end B plane 1
BM2B double Bending moment end B plane 2
TS1 double Shear plane 1
TS2 double Shear plane 2
AF double Axial Force
TRA integer Torque
DOMAIN_ID integer Domain identifier
BEAM EID integer Element identification number
FORCE integer Element force structure for BEAM
DOMAIN_ID integer Domain identifier
BUSH EID integer Element identification number
FX double Force x
FY double Force y
FZ double Force z
MX double Membrane force in x
MY double Membrane force in y
MZ integer Bending moment in z-direction
DOMAIN_ID integer Domain identifier
CONROD/ROD EID integer Element identification number
AF double Axial Force
TRQ double Torque
DOMAIN_ID integer Domain identifier
ELAS1 EID integer Element identification number
F double Force
DOMAIN_ID integer Domain identifier
TRIA3/QUAD4 EID integer Element identification number
FORCE double Force
DOMAIN_ID integer Domain identifier
QUAD8 EID integer Element identification number
TERM character Character string
FORCE double Force
DOMAIN_ID integer Domain identifier
ROD EID integer Element identification number
AF character Axial Force
TRQ double Torque
DOMAIN_ID integer Domain identifier
SHEAR EID integer Element identification number
F41 double Force 4 to 1
F21 double Force 2 to 1
F12 double Force 1 to 2
F32 double Force 3 to 2
F23 double Force 2 to 3
F43 double Force 4 to 3
F14 double Force 1 to 4
KF1 double Kick Force on 1
S12 double Shear 1 2
KF2 double Kick Force on 2
S23 double Shear 2 3
KF3 double Kick Force on 3
S34 double Shear 3 4
KF4 double Kick Force on 4
S41 double Shear 4 1
DOMAIN_ID integer Domain identifier
TRIA6 EID integer Element identification number
TERM character Location
FORCE double Data structure defined in typedef section
DOMAIN_ID integer Domain identifier
The following are the datasets within the ELEMENTAL/STRESS group.
Table 6. OPTISTRUCT/RESULT/ELEMENTAL/STRESS
Dataset Name Field Type Description
BAR* EID integer Element identification number
X1A double SA1
X2A double SA2
X3A double SA3
X4A double SA4
X double Axial
MAXA double SA maximum
MINA double SA minimum
MST double Margin of Safety in Tension
X1B double SB1
X2B double SB2
X3B double SB3
X4B double SB4
MAXB double SB maximum
MINB double SB minimum
MSC double Margin of Safety in Compression
DOMAIN_ID integer Domain identifier
BEAM* EID integer Element identification number
SS integer Strain and stress structure for BEAM
DOMAIN_ID integer Domain identifier
BUSH* EID integer Element identification number
TX double Shear force in x-direction
TY double Shear force in y-direction
TZ double Shear force in z-direction
RX double Rotation in x-direction
MY double Rotation in y-direction
MZ integer Rotation in z-direction
DOMAIN_ID integer Domain identifier
CONROD*/ROD* EID integer Element identification number
AF double Axial Force
TRQ double Torque
DOMAIN_ID integer Domain identifier
ELAS1* EID integer Element identification number
S double Stress
DOMAIN_ID integer Domain identifier
TRIA3*/QUAD4* EID integer Element identification number
FD1 double Fiber distance (Z1)
X1 double Normal in X at Z1
Y1 double Normal in Y at Z1
XY1 double Shear in XY at Z1
FD2 double Fiber distance (Z2)
X2 double Normal in X at Z2
Y2 double Normal in Y at Z2
XY2 double Shear in XY at Z2
DOMAIN_ID integer Domain identifier
QUAD8* EID integer Element identification number
TERM character Character string
SS double Data structure defined in typedef section.
DOMAIN_ID integer Domain identifier
ROD* EID integer Element identification number
A double Axial stress
MSA double Axial Safety Margin
T double Total stress
MST double Margin of Safety in Tension
DOMAIN_ID integer Domain identifier
SHEAR* EID integer Element identification number
TMAX double Maximum Shear
TAVG double Average Shear
MS double Margin of Safety
DOMAIN_ID double Domain identifier
TETRA* EID integer Element identification number.
CID integer Stress Coordinate System
CTYPE character Coordinate System Type (BCD)
NODEF integer Number of Active Points.
SS GRID_SS Grid strain and stress structure.
DOMAIN_ID integer Domain identifier
TRIA3* EID integer Element identification number.
SS CENTER_2D_SS Data structure defined in typedef section.
DOMAIN_ID integer Domain identifier
TRIA6* EID integer Element identification number.
TERM character Location
SS GRID_2D_SS Data structure defined in typedef section.
DOMAIN_ID integer Domain identifier

* These datasets are also applicable to the ELEMENTAL/STRAIN group.

The following are the datasets within the NODAL/APPLIED_LOAD group.
Table 7. OPTISTRUCT/RESULT/NODAL/APPLIED_LOAD
Dataset Name Field Type Description
APPLIED_LOAD ID integer Grid identification number
X double X component
Y double Y component
Z double Z component
RX double RX component
RY double RY component
RZ double RZ component
DOMAIN_ID integer Domain identifier
DISPLACEMENT ID integer Grid identification number
X double X component
Y double Y component
Z double Z component
RX double RX component
RY double RY component
RZ double RZ component
_nmd_5rb"> DOMAIN_ID integer Domain identifier
EIGENVECTOR ID integer Grid identification number
X double X component
Y double Y component
Z double Z component
RX double RX component
RY double RY component
RZ double RZ component
DOMAIN_ID integer Domain identifier
MPC_FORCE ID integer Grid identification number
X double X component
Y double Y component
Z double Z component
RX double RX component
RY double RY component
RZ double RZ component
DOMAIN_ID integer Domain identifier
SPC_FORCE ID integer Grid identification number
X double X component
Y double Y component
Z double Z component
RX double RX component
RY double RY component
RZ double RZ component
DOMAIN_ID integer Domain identifier

Reading Data

Examples for reading in C and Python are available here.

Minimum requirements are:
  • Python: h5py, numpy
  • C: hdf5 and hdf5_hl library

Python Example 1: Reading displacement from .h5 file

This example is for reading displacement data from an .h5 file.
# ****************************************************** 
# Example 1: Reading displacement from h5 file
# ****************************************************** 

import h5py
def ex1():
    # file path
    inp_file = "cbar_strstn_static.h5"

    # open file in read-only mode
    f = h5py.File(inp_file, "r")

    # DISPLACEMENT path
    disp_path = "/OPTISTRUCT/RESULT/NODAL/DISPLACEMENT"

    # acquire DISP table
    t = f[disp_path]

    # print data
    print('DISPLACEMENT:\n')
    print(t[:])
    f.close()

if __name__ == "__main__":
    ex1()

Python Example 2: Reading specific data from displacement in .h5 file

This example demonstrates accessing specific data in displacements. Here, data is filtered and displacement of grid #17 is obtained.
# ****************************************************** 
# Example 2: Reading specific data from displacement in h5 file
# ****************************************************** 

# In this example, some senior functions would be used
# to show how to access specific data

import h5py
import numpy as np

def ex1_2():
    # file path
    inp_file = "cbar_strstn_static.h5"

    # open file in read-only mode
    f = h5py.File(inp_file, "r")

    # DISPLACEMENT path
    disp_path = "/OPTISTRUCT/RESULT/NODAL/DISPLACEMENT"

    # acquire DISP table
    t = f[disp_path]

    # 1. query all field name in this table
    print("All fields in DISP table:\n")
    for name in t.dtype.fields.keys():
        print(name, end="  ")

    # 2. filter ID data

    fn = 'ID'
    ids = t[fn]
    print("All ID:\n")
    print(ids[:])

    # 3. get disp of grid 17
    # for this one, numpy is needed

    id = 17
    arr_ids = np.array(ids)
    idx = np.where(arr_ids == id)
    disp_17 = t[idx]

    print("The DISP of grid 17: \n")
    print(disp_17)
    f.close()


if __name__ == "__main__":
    ex1_2()

Python Example 3: Reading Stresses from .h5 file

This example demonstrates reading CHEXA stress results from an .h5 file (dang_van_tbl_smallshr.h5).
# ****************************************************** 
# Example 3: Reading CHEXA stresses from h5 file
# ****************************************************** 

import h5py

def printbable(name, n):

    if isinstance(n, h5py.Dataset):
        # this is a dataset(table)
        print("the data of {} is :\n".format(name))
        print(n[:])

def ex2():
    inp_file = "dang_van_tbl_smallshr.h5"

    # open file in read-only mode
    f = h5py.File(inp_file, 'r')

    stress_path = '/OPTISTRUCT/RESULT/ELEMENTAL/STRESS'

    # visit all table under STRESS group and print them out

    g = f[stress_path]
    g.visititems(printbable)


if __name__ == "__main__":
    ex2()


    fn = 'ID'

C Examples

The main function is given by:
#include "ex.h"

int main() {
    ex2();
} 
#ifndef CEXPFORH5_EX_H
#define CEXPFORH5_EX_H

int ex1();
int ex2();

#endif //CEXPFORH5_EX_H

C Example 1: Reading displacements and printing

This example demonstrates reading CHEXA stresses from an .h5 file (cbar_strstn_static.h5).
# ****************************************************** 
# Example 1: Reading displacements and printing
# ****************************************************** 
#include "hdf5.h"
#include "hdf5_hl.h"
#include <stdlib.h>

#include "ex.h"

#define FILE    "cbar_strstn_static.h5"
#define TABLE_NAME "/OPTISTRUCT/RESULT/NODAL/DISPLACEMENT"

typedef struct Disp {
    long long id;   // grid id
//    double d[6];  // displacement
    double x;
    double y;
    double z;
    double rx;
    double ry;
    double rz;
    long long domid;  //domain_id
} Disp;

int ex1() {

    herr_t re = 0;

    size_t dst_size = sizeof(Disp);
    size_t dst_offset[]=  {
        HOFFSET(Disp,id),
        HOFFSET(Disp, x),
        HOFFSET(Disp, y),
        HOFFSET(Disp, z),
        HOFFSET(Disp, rx),
        HOFFSET(Disp, ry),
        HOFFSET(Disp, rz),
        HOFFSET(Disp,domid)
    };

    Disp disp;
    size_t dst_sizes[] = {
        sizeof(disp.id),
        sizeof(disp.x),
        sizeof(disp.y),
        sizeof(disp.z),
        sizeof(disp.rx),
        sizeof(disp.ry),
        sizeof(disp.rz),
        sizeof(disp.domid)
    };

    //open file in read-only mode
    hid_t file_id = H5Fopen(FILE,H5F_ACC_RDONLY,H5P_DEFAULT);
    if (file_id < 0) {
        printf("Error: file %s is not here\n",FILE);
        return 0;
    }

    hsize_t nfields, nrecords;
    /* Get table info */
    if (H5TBget_table_info(file_id,TABLE_NAME,&nfields,&nrecords) < 0) {
        printf("Error: Table %s is not here\n",TABLE_NAME);
        goto endact;
    }
    if (nrecords == 0 || nfields == 0) {
        printf("The nrecords or nfields of %s is 0, return\n",TABLE_NAME);
        goto endact;
    }

    Disp* dst_buf = NULL;
    dst_buf = (Disp*)malloc(nrecords * dst_size);
    if (!dst_buf) {
        printf("Error: malloc for rstbuf fail\n");
        goto endact;
    }

    // read disp
    if (H5TBread_table(file_id,TABLE_NAME,dst_size,dst_offset,dst_sizes,dst_buf) < 0) {
        printf("Error: read table fail\n");
        goto clearmem;
    }

    //print disp
    for (int i = 0; i < nrecords;i++) {
        printf("GRID %lld: %e, %e, %e, %e, %e, %e, %lld\n",
               dst_buf[i].id,
               dst_buf[i].x,
               dst_buf[i].y,
               dst_buf[i].z,
               dst_buf[i].rx,
               dst_buf[i].ry,
               dst_buf[i].rz,
               dst_buf[i].domid);
    }

clearmem:
    if (dst_buf!=NULL) free(dst_buf);
endact:
    H5Fclose(file_id);

    return 0;
}

C Example 2: Reading stresses from CHEXA element and printing

This example also helps understand the procedure for working with arrays in an .h5 file (dang_van_tbl_smallshr.h5).
# ****************************************************** 
# Example 2: Reading stresses from CHEXA element and printing
# ****************************************************** 

#include "hdf5.h"
#include "hdf5_hl.h"
#include <stdlib.h>

#include "ex.h"
#define FILE    "dang_van_tbl_smallshr.h5"
#define TABLE_NAME "/OPTISTRUCT/RESULT/ELEMENTAL/STRESS/HEXA"
typedef struct HEXA {
    long long id;   // grid id
    long long cid;
    char ctype[8];
    long long nodef;
    long long grid[9];
    double x[9];
    double y[9];
    double z[9];
    double rx[9];
    double ry[9];
    double rz[9];
    long long domid;  //domain_id
} HEXA;

int ex2 () {
    herr_t re = 0;

    size_t dst_size = sizeof(HEXA);
    size_t dst_offset[]=  {
            HOFFSET(HEXA,id),
            HOFFSET(HEXA,cid),
            HOFFSET(HEXA,ctype),
            HOFFSET(HEXA,nodef),
            HOFFSET(HEXA,grid),
            HOFFSET(HEXA, x),
            HOFFSET(HEXA, y),
            HOFFSET(HEXA, z),
            HOFFSET(HEXA, rx),
            HOFFSET(HEXA, ry),
            HOFFSET(HEXA, rz),
            HOFFSET(HEXA,domid)
    };

    HEXA hexa;
    size_t dst_sizes[] = {
            sizeof(hexa.id),
            sizeof(hexa.cid),
            sizeof(hexa.ctype),
            sizeof(hexa.nodef),
            sizeof(hexa.grid),
            sizeof(hexa.x),
            sizeof(hexa.y),
            sizeof(hexa.z),
            sizeof(hexa.rx),
            sizeof(hexa.ry),
            sizeof(hexa.rz),
            sizeof(hexa.domid)
    };

    //open file in read-only mode
    hid_t file_id = H5Fopen(FILE,H5F_ACC_RDONLY,H5P_DEFAULT);
    if (file_id < 0) {
        printf("Error: file %s is not here\n",FILE);
        return 0;
    }

    hsize_t nfields, nrecords;
    /* Get table info */
    if (H5TBget_table_info(file_id,TABLE_NAME,&nfields,&nrecords) < 0) {
        printf("Error: Table %s is not here\n",TABLE_NAME);
        goto endact;
    }
    if (nrecords == 0 || nfields == 0) {
        printf("The nrecords or nfields of %s is 0, return\n",TABLE_NAME);
        goto endact;
    }

    HEXA* dst_buf = NULL;
    dst_buf = (HEXA*)malloc(nrecords * dst_size);
    if (!dst_buf) {
        printf("Error: malloc for rstbuf fail\n");
        goto endact;
    }

    // read disp
    if (H5TBread_table(file_id,TABLE_NAME,dst_size,dst_offset,dst_sizes,dst_buf) < 0) {
        printf("Error: read table fail\n");
        goto clearmem;
    }

    //print disp
    for (int i = 0; i < nrecords;i++) {
        printf("HEXA %lld: %lld, %s, %lld, %lld\n",
               dst_buf[i].id,
               dst_buf[i].cid,
               dst_buf[i].ctype,
               dst_buf[i].nodef,
               dst_buf[i].domid);

        for (int j = 0; j < 9 ;j++) {
            printf("\t %lld, %e, %e, %e, %e, %e, %e",
                   dst_buf[i].grid[j],
                   dst_buf[i].x[j],
                   dst_buf[i].y[j],
                   dst_buf[i].z[j],
                   dst_buf[i].rx[j],
                   dst_buf[i].ry[j],
                   dst_buf[i].rz[j]);
        }
        printf("\n");
    }

    clearmem:
    if (dst_buf!=NULL) free(dst_buf);
    endact:
    H5Fclose(file_id);

    return 0;
}