Commit b540f156 authored by Gurecky, William's avatar Gurecky, William
Browse files

Merge branch 'pod_rom_updates' into 'main'

update to pod rom script for demo

See merge request dt-hydro/dt-hydro-cfd!9
parents 69883fd3 c785da01
Loading
Loading
Loading
Loading
+193 −0
Original line number Diff line number Diff line
"""
Visualization for the propor Orthogonal decomposition (POD)
reduced order model (ROM) of the 3D cfd data through the
turbine chamber.
This Visualization script depends on the plotly and dash
python packages for fast live-updating 3D plots.

NOTE: You must FIRST run the pod_cfd_model.py script
before executing this script.
The data produced by
the pod_cfd_model.py script is visualized by this script
seperately.  This is to decouple the model from the plotting
procedure so that they may run on seperate processes.

Author: William Gurecky.  wll@ornl.gov.  June 2023
"""
import numpy as np
import h5py
import time
import argparse
# plotly imports
import plotly.graph_objects as go
import plotly.express as px
# dash imports
import dash
from dash import dcc, html
from dash.dependencies import Input, Output
try:
    from dthydro_cfd.rom_cfd.pod_rom import PODInterpModel
except ImportError:
    from pod_rom import PODInterpModel


# Connect to h5 file
parser = argparse.ArgumentParser()
parser.add_argument("-i", help="Input h5 file", type=str, default="db_dynamic_inelastic.h5")
args = parser.parse_args()
db_pod_file = args.i
f_db = h5py.File(db_pod_file, 'r', libver='latest', swmr=True)

app = dash.Dash(__name__)
# html.Div(id='live-vane-angle-text'),
app.layout = html.Div(
    html.Div([
        html.H4('Reduced Order Model (ROM) Live Feed'),
        dcc.Graph(id='live-update-graph-p'),
        dcc.Graph(id='live-update-graph-v'),
        dcc.Graph(id='live-update-graph-vane'),
        dcc.Graph(id='live-update-graph-flow'),
        dcc.Interval(
            id='interval-component',
            interval=500, # in milliseconds
            n_intervals=0
        )
    ])
)

X_POINTS = f_db["X"][:].flatten()
Y_POINTS = f_db["Y"][:].flatten()
Z_POINTS = f_db["Z"][:].flatten()
# data thinning
PTX = np.random.randint(0, len(X_POINTS), size=6000)
P_ = None
from collections import deque
vane_history = deque(maxlen=100)
flow_history = deque(maxlen=100)
time_history = deque(maxlen=100)


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph-p', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live(n):
    global P_
    # Read data from database
    P_ = f_db["P"][:]
    # scale pressure to be consisent with model turbine
    # inlet pressure
    p_inlet = 500.e3  # Pa
    p_scale = p_inlet - np.max(P_)

    fig = px.scatter_3d(
            x=X_POINTS[PTX],
            y=Y_POINTS[PTX],
            z=Z_POINTS[PTX],
            color=P_[PTX] + p_scale,
            range_color=[101.e3, 400.e3],
            opacity=0.95,
            size_max=4,
            title="Pressure (Pa)",
            )
    fig.update_traces(marker=dict(size=3))
    fig.update_layout(
        coloraxis_colorbar=dict(title="Pressure (Pa)",),
    )

    # Draw new figure
#     fig = go.Figure(data=go.Scatter3d(
#         x=X_POINTS[PTX],
#         y=Y_POINTS[PTX],
#         z=Z_POINTS[PTX],
#         mode='markers',
#         marker=dict(size=3, color=P_[PTX], opacity=0.95,
#                     colorbar=dict(thickness=5, title="Pressure (Pa)", ),
#                     ),
#         customdata=P_[PTX],
#         hovertemplate=('%{customdata}%'),
#         ))
    # preserve zoom, pan settings
    # from: https://stackoverflow.com/questions/68798315/how-to-update-plotly-plot-and-keep-ui-settings
    fig['layout']['height'] = 700  # px
    fig['layout']['uirevision'] = 'const'
    return fig


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph-v', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live_v(n):
    # Read data from database
    pred_vx = f_db["VX"][:][PTX]
    pred_vy = f_db["VY"][:][PTX]
    pred_vz = f_db["VZ"][:][PTX]
    v_mag = np.sqrt(pred_vx ** 2. + pred_vy ** 2. + pred_vz ** 2.)

    fig_v = go.Figure(data=[go.Cone(
        x=X_POINTS[PTX],
        y=Y_POINTS[PTX],
        z=Z_POINTS[PTX],
        u=pred_vx,
        v=pred_vy,
        w=pred_vz,
        # sizemode="absolute",
        sizeref=3,
        # colorbar=dict(thickness=8, title="Velocity (m/s)"),
        ),
        go.Scatter3d(
         x=X_POINTS[PTX],
         y=Y_POINTS[PTX],
         z=Z_POINTS[PTX],
         mode='markers',
         marker=dict(size=2, color=v_mag, opacity=0.65,
                     colorbar=dict(thickness=5, title="Velocity (m/s)", ),
                     ),
            )
        ]
        )
    fig_v['layout']['height'] = 700  # px
    fig_v['layout']['uirevision'] = 'const'
    return fig_v


# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph-vane', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live_vane(n):
    global vane_history
    global time_history
    t = f_db["t"][:]
    va = f_db["vane_angle"][:]
    vane_history.append(va[0])
    time_history.append(t[0])

    fig_vane = go.Figure(data=go.Scatter(
        x=np.asarray(list(time_history)),
        y=np.asarray(list(vane_history)),
        ))
    fig_vane['layout']['uirevision'] = 'const'
    return fig_vane

# Multiple components can update everytime interval gets fired.
@app.callback(Output('live-update-graph-flow', 'figure'),
              Input('interval-component', 'n_intervals'))
def update_graph_live_vane(n):
    global flow_history
    global time_history
    t = f_db["t"][:]
    flow = f_db["flow"][:]
    flow_history.append(flow[0])
    print(flow[0])
    time_history.append(t[0])

    fig = go.Figure(data=go.Scatter(
        x=np.asarray(list(time_history)),
        y=np.asarray(list(flow_history)),
        ))
    fig['layout']['uirevision'] = 'const'
    return fig


if __name__ == "__main__":
    # init the dash app
    app.run_server(debug=True)
+203 −26
Original line number Diff line number Diff line
@@ -13,8 +13,10 @@ Author: William Gurecky. wll@ornl.gov. June 2023
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
import argparse
import time
import os
from typing import List
from scipy.interpolate import interp1d, RBFInterpolator
import h5py
try:
@@ -22,8 +24,17 @@ try:
except ImportError:
    from pod_rom import PODInterpModel

# globals
v_i_name = "Velocity[i] (m/s)"
v_j_name = "Velocity[j] (m/s)"
v_k_name = "Velocity[k] (m/s)"
p_name = "Static Pressure (Pa)"
#v_i_name = "Velocity in Rotating[i] (m/s)"
#v_j_name = "Velocity in Rotating[j] (m/s)"
#v_k_name = "Velocity in Rotating[k] (m/s)"

def construct_pod_model(snapshot_h5file, data_name="Pressure (Pa)", n_pod_modes=5):

def construct_pod_model(snapshot_h5file, data_name="Static Pressure (Pa)", n_pod_modes=5):
    # read the snapshot data from the hdf5 file
    h5f = h5py.File(snapshot_h5file, mode='r')
    xyz_points = h5f["/points"][:]
@@ -56,29 +67,95 @@ class PodCfdModel(object):
    """
    Creates a Reduced Order Model (ROM) of the 3D CFD data
    of the turbine chamber.

    Args:
        snapshot_h5file: HDF5 file containing preprocessed CFD data.
            See the preprocess_cfd.py for details on generating this file.
        data_name: Name of the field to reconstruct via the POD model.
        n_pod_modes: Number of POD modes to retain in the ROM.  A larger number of retained
            POD modes results in greateer accuracy at the expense of more computation time.
        min_vane_angle:  min vane angle (model only works
                         between min and max CFD vane angle data)
        min_vane_angle:  max vane angle (model only works
                         between min and max CFD vane angle data)
    """
    def __init__(self, snapshot_h5file: str, data_name: str="Pressure (Pa)", n_pod_modes: int=7):
    def __init__(self, snapshot_h5file: str, data_name: str="Static Pressure (Pa)", n_pod_modes: int=7, min_vane_angle=11.11, max_vane_angle=13.874, **kwargs):
        pod_model, xyz_points = construct_pod_model(snapshot_h5file, data_name, n_pod_modes)
        self._pod_model = pod_model
        self._xyz_points = xyz_points
        self._min_vane_angle = min_vane_angle
        self._max_vane_angle = max_vane_angle
        self._max_field_value = kwargs.get("max_field_value", 800e3)
        self._min_field_value = kwargs.get("min_field_value", -100e3)

    def predict(self, vane_angle: float, min_vane_angle: float=4., max_vane_angle: float=9.):
    def predict(self, vane_angle: float) -> np.ndarray:
        """
        Evaluate the POD ROM.

        Args:
            vane_angle:  turbine guide vane angle in degrees
        """
        va = np.clip(vane_angle, self._min_vane_angle, self._max_vane_angle)
        return np.clip(self._pod_model.predict(va), self._min_field_value, self._max_field_value)

    @property
    def xyz_points(self) -> np.ndarray:
        """
        Locations at which the POD ROM is evaulated at
        """
        return self._xyz_points


class SegmentedPodCfdModel(object):
    """
    Contains several sub-POD ROM models that can be combined to form one output.
    Requires that each sub-POD ROM has the exact same inputs. Particularly useful when
    sharp boundaries in the flow or geometry exist in the full model: A different POD
    model can be fitted to the flow field in each region and later rejoined
    using this class.

    Args:
        snapshot_h5files: List of HDF5 files containing preprocessed CFD data.
            See the preprocess_cfd.py for details on generating this file.
        data_name: Name of the field to reconstruct via the POD model.
        n_pod_modes: Number of POD modes to retain in the ROM.  A larger number of retained
            POD modes results in greateer accuracy at the expense of more computation time.
        min_vane_angle:  min vane angle (model only works
                         between min and max CFD vane angle data)
        min_vane_angle:  max vane angle (model only works
                         between min and max CFD vane angle data)
    """
        va = np.clip(vane_angle, min_vane_angle, max_vane_angle)
        return self._pod_model.predict(va)
    def __init__(self, snapshot_h5files: List[str], data_name: str="Static Pressure (Pa)", n_pod_modes: int=7, min_vane_angle=11.11, max_vane_angle=13.874, **kwargs):
        self._pod_cfd_models = []
        if isinstance(data_name, str):
            for i, snapshot_h5file in enumerate(snapshot_h5files):
                self._pod_cfd_models.append(PodCfdModel(snapshot_h5file, data_name, n_pod_modes, min_vane_angle, max_vane_angle, **kwargs))
        else:
            assert len(data_name) == len(snapshot_h5files)
            for i, snapshot_h5file in enumerate(snapshot_h5files):
                self._pod_cfd_models.append(PodCfdModel(snapshot_h5file, data_name[i], n_pod_modes, min_vane_angle, max_vane_angle, **kwargs))

    def predict(self, vane_angle: float) -> np.ndarray:
        """
        Evaluate the POD ROM.

        Args:
            vane_angle:  turbine guide vane angle in degrees
        """
        seg_results = []
        for pod_model in self._pod_cfd_models:
            seg_results.append(pod_model.predict(vane_angle))
        return np.concatenate(seg_results, axis=0)

    @property
    def xyz_points(self):
        return self._xyz_points
    def xyz_points(self) -> np.ndarray:
        """
        Locations at which the POD ROM is evaulated at
        """
        seg_xyz = []
        for pod_model in self._pod_cfd_models:
            seg_xyz.append(pod_model._xyz_points)
        return np.concatenate(seg_xyz, axis=0)


def test_pod_cfd_model(use_plotly=True,
@@ -86,20 +163,20 @@ def test_pod_cfd_model(use_plotly=True,
                       n_pod_modes=7):
    # create the reduced order model(s)
    pod_model = PodCfdModel(
            snapshot_h5file, data_name="Pressure (Pa)",
            snapshot_h5file, data_name=p_name,
            n_pod_modes=n_pod_modes)
    xyz_points = pod_model.xyz_points

    pod_model_vx = PodCfdModel(
            snapshot_h5file, data_name="Velocity[i] (m/s)")
            snapshot_h5file, data_name=v_i_name)
    pod_model_vy = PodCfdModel(
            snapshot_h5file, data_name="Velocity[j] (m/s)")
            snapshot_h5file, data_name=v_j_name)
    pod_model_vz = PodCfdModel(
            snapshot_h5file, data_name="Velocity[k] (m/s)")
            snapshot_h5file, data_name=v_k_name)

    # evaluate the pod model at an vane angle not in training set
    ts = time.time()
    current_vane_angle = 8.02
    current_vane_angle = 12.5
    pred_p = pod_model.predict(current_vane_angle)
    pred_vx = pod_model_vx.predict(current_vane_angle)
    pred_vy = pod_model_vy.predict(current_vane_angle)
@@ -123,7 +200,7 @@ def test_pod_cfd_model(use_plotly=True,
            z=Z.flatten(),
            mode='markers',
            marker=dict(size=4, color=values, opacity=0.95,
                        colorbar=dict(thickness=5, title="Pressure (Pa)")),
                        colorbar=dict(thickness=5, title="Static Pressure (Pa)")),
            customdata=values,
            hovertemplate=('%{customdata}%'),
            ))
@@ -137,7 +214,7 @@ def test_pod_cfd_model(use_plotly=True,
            v=pred_vy,
            w=pred_vz,
            sizemode="absolute",
            sizeref=150,
            # sizeref=150,
            colorbar=dict(thickness=8, title="Velocity (m/s)"),
            ))
        fig_v.show()
@@ -145,6 +222,7 @@ def test_pod_cfd_model(use_plotly=True,
        print("Time to make plot: %0.4e (sec)" % (te-ts))

    else:
        # use matplotlib
        # create 3d plot figure of predicted pressure distribution
        ts = time.time()
        fig = plt.figure()
@@ -159,19 +237,99 @@ def test_pod_cfd_model(use_plotly=True,
        print("Time to make plot: %0.4e (sec)" % (te-ts))


def test_pod_segmented_cfd_model(snapshot_h5files, n_pod_modes=7, rotating_frame=True):
    assert len(snapshot_h5files) == 3
    p_data_names = ["Static Pressure (Pa)"] * 3
    v_i_data_names = [
        "Velocity[i] (m/s)",
        "Velocity in Rotating[i] (m/s)" if rotating_frame else "Velocity[i] (m/s)",
        "Velocity[i] (m/s)",
        ]
    v_j_data_names = [
        "Velocity[j] (m/s)",
        "Velocity in Rotating[j] (m/s)" if rotating_frame else "Velocity[j] (m/s)",
        "Velocity[j] (m/s)",
        ]
    v_k_data_names = [
        "Velocity[k] (m/s)",
        "Velocity in Rotating[k] (m/s)" if rotating_frame else "Velocity[k] (m/s)",
        "Velocity[k] (m/s)",
        ]

    # create the reduced order model(s)
    pod_model = SegmentedPodCfdModel(
            snapshot_h5files, data_name=p_data_names,
            n_pod_modes=n_pod_modes)
    xyz_points = pod_model.xyz_points

    pod_model_vx = SegmentedPodCfdModel(
            snapshot_h5files, data_name=v_i_data_names, n_pod_modes=n_pod_modes)
    pod_model_vy = SegmentedPodCfdModel(
            snapshot_h5files, data_name=v_j_data_names, n_pod_modes=n_pod_modes)
    pod_model_vz = SegmentedPodCfdModel(
            snapshot_h5files, data_name=v_k_data_names, n_pod_modes=n_pod_modes)

    # evaluate the pod model at an vane angle not in training set
    ts = time.time()
    current_vane_angle = 12.8
    pred_p = pod_model.predict(current_vane_angle)
    pred_vx = pod_model_vx.predict(current_vane_angle)
    pred_vy = pod_model_vy.predict(current_vane_angle)
    pred_vz = pod_model_vz.predict(current_vane_angle)
    pred_vmag = np.sqrt(pred_vx**2 + pred_vy**2 + pred_vz**2)
    te = time.time()
    print("Time to eval POD ROM: %0.4e (sec)" % (te-ts))

    X = np.asarray(xyz_points[:, 0], dtype=np.float32)
    Y = np.asarray(xyz_points[:, 1], dtype=np.float32)
    Z = np.asarray(xyz_points[:, 2], dtype=np.float32)
    values = np.asarray(pred_p, dtype=np.float32)

    # make plots
    import plotly.graph_objects as go
    import plotly
    ts = time.time()
    fig_p = go.Figure(data=go.Scatter3d(
        x=X.flatten(),
        y=Y.flatten(),
        z=Z.flatten(),
        mode='markers',
        marker=dict(size=2, color=values, opacity=0.95,
                    colorbar=dict(thickness=5, title="Static Pressure (Pa)")),
        customdata=values,
        hovertemplate=('%{customdata}%'),
        ))
    fig_p.show()

    fig_v = go.Figure(data=go.Cone(
        x=X.flatten(),
        y=Y.flatten(),
        z=Z.flatten(),
        u=pred_vx,
        v=pred_vy,
        w=pred_vz,
        #sizemode="absolute",
        sizeref=25,
        colorbar=dict(thickness=8, title="Velocity (m/s)"),
        ))
    fig_v.show()
    te = time.time()
    print("Time to make plot: %0.4e (sec)" % (te-ts))


def test_dynamic_pod_model(snapshot_h5file="cfd_pod_snapshots.h5", n_pod_modes=7):
    # create the reduced order model(s)
    pod_model = PodCfdModel(
            snapshot_h5file, data_name="Pressure (Pa)",
            snapshot_h5file, data_name=p_name,
            n_pod_modes=n_pod_modes)
    xyz_points = pod_model.xyz_points

    pod_model_vx = PodCfdModel(
            snapshot_h5file, data_name="Velocity[i] (m/s)")
            snapshot_h5file, data_name=v_i_name)
    pod_model_vy = PodCfdModel(
            snapshot_h5file, data_name="Velocity[j] (m/s)")
            snapshot_h5file, data_name=v_j_name)
    pod_model_vz = PodCfdModel(
            snapshot_h5file, data_name="Velocity[k] (m/s)")
            snapshot_h5file, data_name=v_k_name)

    # update vane angle and store data in tmp hdf5 file
    # acting as a database
@@ -190,9 +348,9 @@ def test_dynamic_pod_model(snapshot_h5file="cfd_pod_snapshots.h5", n_pod_modes=7
    f_db.create_dataset("Z", data=Z)
    f_db.flush()

    current_vane_angle = 4.0
    min_vane_angle = 4.0
    max_vane_angle = 9.0
    current_vane_angle = 12.5
    min_vane_angle = 11.11
    max_vane_angle = 13.874
    def get_test_vane_angle(t):
        """
        Returns a vane angle between min and max val
@@ -247,5 +405,24 @@ def test_dynamic_pod_model(snapshot_h5file="cfd_pod_snapshots.h5", n_pod_modes=7


if __name__ == "__main__":
    # test_pod_cfd_model()
    test_dynamic_pod_model()
    parser = argparse.ArgumentParser()
    parser.add_argument("-i", help="Input POD snapshot file(s).", type=str, nargs='+', default=["cfd_pod_snapshots.h5"])
    parser.add_argument("--dynamic", help="Run in dynamic test mode with moving vane angle", type=int, default=0)
    parser.add_argument("--n_pod_modes", help="Run in dynamic test mode with moving vane angle", type=int, default=7)
    parser.add_argument("--rotating_frame", help="Use rotating reference frame for velocity data in the runner", type=int, default=0)
    args = parser.parse_args()
    if len(args.i) == 1:
        if bool(args.dynamic):
            test_dynamic_pod_model(
                    snapshot_h5file=args.i[0],
                    n_pod_modes=args.n_pod_modes)
        else:
            test_pod_cfd_model(
                    use_plotly=True, snapshot_h5file=args.i[0],
                    n_pod_modes=args.n_pod_modes)
    else:
        test_pod_segmented_cfd_model(
                snapshot_h5files=args.i,
                n_pod_modes=args.n_pod_modes,
                rotating_frame=bool(args.rotating_frame),
                )
+221 −26

File changed.

Preview size limit exceeded, changes collapsed.

+81 −9
Original line number Diff line number Diff line
@@ -279,10 +279,10 @@ def alder_inelastic(t_end=20., h_in=60., h_out=0.0, pid_control=True, *args, **k
            rom_vane_angle = np.rad2deg(a_turb)
            # NOTE: Current POD ROM snapshot data only valid between
            # 4.0 and 9.0 degrees of vane opening!
            pred_p = pod_model_p.predict(rom_vane_angle, min_vane_angle=4., max_vane_angle=9.)
            pred_vx = pod_model_vx.predict(rom_vane_angle, min_vane_angle=4., max_vane_angle=9.)
            pred_vy = pod_model_vy.predict(rom_vane_angle, min_vane_angle=4., max_vane_angle=9.)
            pred_vz = pod_model_vz.predict(rom_vane_angle, min_vane_angle=4., max_vane_angle=9.)
            pred_p = pod_model_p.predict(rom_vane_angle)
            pred_vx = pod_model_vx.predict(rom_vane_angle)
            pred_vy = pod_model_vy.predict(rom_vane_angle)
            pred_vz = pod_model_vz.predict(rom_vane_angle)
            pred_vmag = np.sqrt(pred_vx**2 + pred_vy**2 + pred_vz**2)
            print("ROM Vane angle (deg): ", rom_vane_angle)
            print("ROM Max, Min 3D P (Pa): ", max(pred_p), min(pred_p))
@@ -400,6 +400,65 @@ def alder_inelastic(t_end=20., h_in=60., h_out=0.0, pid_control=True, *args, **k
    plt.close()


def write_to_h5_db(f_db, res_dict):
    t = res_dict["time"]
    current_vane_angle = np.rad2deg(res_dict["turbine_vane_angle"])
    pred_p = res_dict['3d_pred_p']
    pred_vx = res_dict['3d_pred_vx']
    pred_vy = res_dict['3d_pred_vy']
    pred_vz = res_dict['3d_pred_vz']
    pred_flow = res_dict['flow_rate']
    p_s = res_dict['penstock_pressures']
    s = res_dict['penstock_pressure_points']
    turb_power = res_dict['turbine_shaft_power']
    turb_w = res_dict['turbine_rotation_rate']

    # 3D points for turbine chamber plots
    xyz_points = res_dict['3d_xyz_points']
    X = xyz_points[:, 0]
    Y = xyz_points[:, 1]
    Z = xyz_points[:, 2]

    try:
        # overwrite datasets
        f_db["P"][...] = pred_p
        f_db["VX"][...] = pred_vx
        f_db["VY"][...] = pred_vy
        f_db["VZ"][...] = pred_vz
        # 1D system vars
        f_db["vane_angle"][...] = [current_vane_angle]
        f_db["t"][...] = [float(t)]
        f_db["P_s"][...] = p_s
        f_db["s"][...] = s
        f_db["flow"][...] = [pred_flow]
        f_db["turb_w"][...] = [turb_w]
        f_db["turb_power"][...] = [turb_power]
    except:
        # create new datasets
        f_db.create_dataset("X", data=X)
        f_db.create_dataset("Y", data=Y)
        f_db.create_dataset("Z", data=Z)
        # turbine chamber 3d
        f_db.create_dataset("P", data=pred_p)
        f_db.create_dataset("VX", data=pred_vx)
        f_db.create_dataset("VY", data=pred_vy)
        f_db.create_dataset("VZ", data=pred_vz)
        # 1D system vars
        f_db.create_dataset("vane_angle", data=[current_vane_angle])
        f_db.create_dataset("t", data=[float(t)])
        # 1D pressure along penstock
        f_db.create_dataset("P_s", data=p_s)
        # 1D locations along penstock (x-axis var)
        f_db.create_dataset("s", data=s)
        # flow rate
        f_db.create_dataset("flow", data=[pred_flow])
        # turbine rotation rate
        f_db.create_dataset("turb_w", data=[turb_w])
        # turbine power
        f_db.create_dataset("turb_power", data=[turb_power])
    f_db.flush()


if __name__ == "__main__":
    import argparse
    parser = argparse.ArgumentParser()
@@ -408,11 +467,24 @@ if __name__ == "__main__":
    parser.add_argument("-h_out", type=float, help="tailwater depth", default=0.0)  # 6.87
    parser.add_argument("--pod_rom_snapshots", type=str, help="file name of CFD POD snapshots", default="")
    args = parser.parse_args()
    for res_dict in alder_inelastic(

    # Open live hdf5 file for logging
    db_pod_file = "db_dynamic_inelastic.h5"
    if os.path.exists(db_pod_file):
        os.remove(db_pod_file)
    f_db = h5py.File(db_pod_file, 'w', libver='latest')
    f_db.swmr_mode = True
    f_db.flush()

    for i, res_dict in enumerate(alder_inelastic(
            t_end=args.t_f,
            h_in=args.h_in,
            h_out=args.h_out,
            pod_rom_snapshots=args.pod_rom_snapshots):
        # print(res_dict)
        # Could do realtime additional plotting here
        pass
            pod_rom_snapshots=args.pod_rom_snapshots)):
        # write results to database every 100 steps
        if i % 100 == 0:
            write_to_h5_db(f_db, res_dict)
            time.sleep(0.25)

    # clean up
    f_db.close()
+1 −1
Original line number Diff line number Diff line
@@ -24,7 +24,7 @@ setup(
    description='CFD models to support a digital twin package for hydropower systems',
    author='William Gurecky',
    platforms=["Linux", "Mac OS-X"],
    install_requires=['numpy>=1.7.0', 'scipy>=0.12.0', 'six', 'matplotlib'],
    install_requires=['numpy>=1.7.0', 'scipy>=0.12.0', 'six', 'matplotlib', 'numba', 'scikit-learn'],
    package_data={'': ['*.txt']},
    author_email='gureckywl@ornl.gov',
    keywords='digital-twin, hydropower, cfd',