Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
149 changes: 149 additions & 0 deletions examples/3d_animated_dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
#!/usr/bin/env python3
"""Animated Dashboard with 3D Views Example.

This example demonstrates how to create an animated Plotly dashboard
that includes 3D scatter plots and 3D surface views alongside 2D
visualizations, with Play/Pause playback controls.

Features demonstrated:
1. Animated multi-panel dashboard (3x3 grid)
2. 3D scatter plot of velocity vectors colored by magnitude
3. 3D surface plot of velocity magnitude
4. Playback controls (Play/Pause, timeline slider)
5. Time evolution of flow fields

Usage:
python examples/3d_animated_dashboard.py

Requirements:
- cfd_python package (pip install -e ../cfd-python)
- cfd_viz package
- plotly package
"""

import sys
from pathlib import Path

import numpy as np

try:
import cfd_python
except ImportError:
print("Error: cfd_python package not installed.")
print("Install with: pip install -e ../cfd-python")
sys.exit(1)

from cfd_viz.common import read_vtk_file
from cfd_viz.interactive import (
create_animated_dashboard,
create_interactive_frame_collection,
)


def run_transient_simulations() -> list:
"""Run simulations at multiple timesteps.

Returns:
List of output VTK file paths.
"""
output_dir = Path("output/vtk/3d_animated_transient")
output_dir.mkdir(parents=True, exist_ok=True)

total_steps = 300
output_interval = 50

print("Running transient simulations...")
print(" Grid: 60 x 60")
print(f" Total steps: {total_steps}")
print(f" Output interval: {output_interval}")

vtk_files = []
for step in range(output_interval, total_steps + 1, output_interval):
output_file = str(output_dir / f"flow_{step:04d}.vtk")

cfd_python.run_simulation_with_params(
nx=60,
ny=60,
xmin=0.0,
xmax=1.0,
ymin=0.0,
ymax=1.0,
steps=step,
output_file=output_file,
)

print(f" Step {step}: {output_file}")
vtk_files.append(output_file)

return vtk_files


def create_animated_3d_dashboard(vtk_files: list):
"""Create an animated dashboard with 3D views.

Args:
vtk_files: List of VTK file paths (one per timestep).
"""
print("\nLoading simulation frames...")

frames_data = []
time_indices = []

for vtk_file in vtk_files:
data = read_vtk_file(vtk_file)
if data is None:
print(f"Warning: Could not read {vtk_file}")
continue

x, y = data.x, data.y
u, v = data.u, data.v
p = data.get("p", np.zeros_like(u))

frames_data.append((x, y, u, v, p))
time_idx = int(vtk_file.split("_")[-1].split(".")[0])
time_indices.append(time_idx)

print(f"Loaded {len(frames_data)} frames")

# Create frame collection for animated dashboard
frame_collection = create_interactive_frame_collection(frames_data, time_indices)

# Create animated dashboard with 3D views
print("\nCreating animated dashboard with 3D views...")
fig = create_animated_dashboard(
frame_collection,
title="3D Animated Flow Dashboard",
)

output_dir = Path("output/html")
output_dir.mkdir(parents=True, exist_ok=True)

out_path = output_dir / "3d_animated_dashboard.html"
fig.write_html(str(out_path))
print(f" Saved: {out_path}")


def main():
"""Main function."""
print("3D Animated Dashboard Example")
print("=" * 40)

vtk_files = run_transient_simulations()
create_animated_3d_dashboard(vtk_files)

print("\n" + "=" * 40)
print("Done!")
print("\nOutput file (open in browser):")
print(" - output/html/3d_animated_dashboard.html")
print("\nThe dashboard includes:")
print(" - Velocity magnitude heatmap (animated)")
print(" - Velocity vectors (animated)")
print(" - Pressure heatmap (animated)")
print(" - Vorticity heatmap (animated)")
print(" - 3D flow scatter plot (drag to rotate)")
print(" - 3D velocity magnitude surface (drag to rotate)")
print(" - Play/Pause controls and timeline slider")


if __name__ == "__main__":
main()
123 changes: 123 additions & 0 deletions examples/3d_dashboard.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#!/usr/bin/env python3
"""Multi-panel Dashboard with 3D Surface Example.

This example demonstrates how to create a multi-panel interactive
dashboard that includes a 3D surface subplot alongside 2D heatmaps
and vector field visualizations.

Features demonstrated:
1. Multi-panel Plotly dashboard with 2x3 grid layout
2. 3D surface subplot showing velocity magnitude
3. 2D heatmaps for pressure and vorticity
4. Velocity vector field overlay

Usage:
python examples/3d_dashboard.py

Requirements:
- cfd_python package (pip install -e ../cfd-python)
- cfd_viz package
- plotly package
"""

import sys
from pathlib import Path

import numpy as np

try:
import cfd_python
except ImportError:
print("Error: cfd_python package not installed.")
print("Install with: pip install -e ../cfd-python")
sys.exit(1)

from cfd_viz.common import read_vtk_file
from cfd_viz.interactive import create_dashboard_figure, create_interactive_frame


def run_simulation() -> str:
"""Run a steady-state CFD simulation.

Returns:
Path to the output VTK file.
"""
output_file = "output/vtk/3d_dashboard_flow.vtk"
Path("output/vtk").mkdir(parents=True, exist_ok=True)

print("Running simulation: 80x80 grid, 500 steps...")
cfd_python.run_simulation_with_params(
nx=80,
ny=80,
xmin=0.0,
xmax=1.0,
ymin=0.0,
ymax=1.0,
steps=500,
output_file=output_file,
)
print("Simulation complete!")
return output_file


def create_dashboard(vtk_file: str):
"""Create a multi-panel dashboard with 3D surface.

Args:
vtk_file: Path to VTK file with simulation results.
"""
print(f"\nLoading results from: {vtk_file}")

data = read_vtk_file(vtk_file)
if data is None:
print(f"Error: Could not read {vtk_file}")
return

x, y = data.x, data.y
u, v = data.u, data.v
p = data.get("p", np.zeros_like(u))

print(f"Domain: [{x.min():.2f}, {x.max():.2f}] x [{y.min():.2f}, {y.max():.2f}]")
print(f"Grid: {data.nx} x {data.ny}")

output_dir = Path("output/html")
output_dir.mkdir(parents=True, exist_ok=True)

# Create interactive frame (bundles x, y, u, v, p for the dashboard)
frame = create_interactive_frame(x, y, u, v, p=p, time_index=500)

# Create multi-panel dashboard (includes 3D surface subplot)
print("\nCreating multi-panel dashboard with 3D surface...")
fig = create_dashboard_figure(
frame,
title="CFD Flow Dashboard with 3D Surface",
)

out_path = output_dir / "3d_dashboard.html"
fig.write_html(str(out_path))
print(f" Saved: {out_path}")


def main():
"""Main function."""
print("3D Dashboard Example")
print("=" * 40)

vtk_file = run_simulation()
create_dashboard(vtk_file)

print("\n" + "=" * 40)
print("Done!")
print("\nOutput file (open in browser):")
print(" - output/html/3d_dashboard.html")
print("\nThe dashboard includes:")
print(" - Velocity magnitude heatmap")
print(" - Velocity vector field")
print(" - Pressure heatmap")
print(" - Vorticity heatmap")
print(" - Streamlines")
print(" - 3D velocity magnitude surface (drag to rotate)")


if __name__ == "__main__":
main()
Loading