import dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
import numpy as np
import plotly.graph_objects as go
from scipy.ndimage import gaussian_filter
# Initialize the Dash app
app = dash.Dash(__name__)
# Function to generate initial fluid flow
def generate_initial_flow(shape=(20, 20, 20)):
flow = np.random.rand(*shape, 3) * 2 - 1
flow = gaussian_filter(flow, sigma=2)
return flow
# Function to update the fluid flow
def update_flow(flow):
perturbation = (np.random.rand(*flow.shape) * 2 - 1) * 0.1
new_flow = flow + perturbation
new_flow = gaussian_filter(new_flow, sigma=1)
return new_flow
# Create initial fluid flow
initial_flow = generate_initial_flow()
# Initial camera position
initial_camera_angle = 0
# Create a 3D plot
def create_3d_plot(flow, angle):
x, y, z = np.mgrid[0:1:20j, 0:1:20j, 0:1:20j]
u, v, w = flow[..., 0], flow[..., 1], flow[..., 2]
fig = go.Figure(data=go.Cone(x=x.flatten(), y=y.flatten(), z=z.flatten(),
u=u.flatten(), v=v.flatten(), w=w.flatten(),
colorscale='Viridis', sizemode='absolute',
anchor="tip", showscale=False))
# Calculate new camera position for rotation
camera_x = 1.2 * np.cos(angle)
camera_y = 1.2 * np.sin(angle)
camera_z = 0.8 # Slightly zoomed in
fig.update_layout(scene=dict(
camera=dict(eye=dict(x=camera_x, y=camera_y, z=camera_z)),
aspectratio=dict(x=1, y=1, z=1),
aspectmode='cube'
))
return fig
# Define the layout of the Dash app
app.layout = html.Div([
html.H1("Navier-Stokes Equation Animation in 3D"),
dcc.Interval(id='interval-component', interval=500, n_intervals=0), # Slowed down to 500 ms
dcc.Graph(id='3d-plot')
])
# Define the callback to update the 3D plot
@app.callback(
Output('3d-plot', 'figure'),
[Input('interval-component', 'n_intervals')]
)
def animate_flow(n):
global initial_flow, initial_camera_angle
initial_flow = update_flow(initial_flow)
initial_camera_angle += 0.05 # Rotate the camera
return create_3d_plot(initial_flow, initial_camera_angle)
# Run the app
if __name__ == '__main__':
app.run_server(debug=True)