summaryrefslogtreecommitdiff
path: root/examples/poiseulle_particles_2d_compare/.nix
diff options
context:
space:
mode:
Diffstat (limited to 'examples/poiseulle_particles_2d_compare/.nix')
-rw-r--r--examples/poiseulle_particles_2d_compare/.nix/derivation.nix100
1 files changed, 100 insertions, 0 deletions
diff --git a/examples/poiseulle_particles_2d_compare/.nix/derivation.nix b/examples/poiseulle_particles_2d_compare/.nix/derivation.nix
index 415bd6a..de2d415 100644
--- a/examples/poiseulle_particles_2d_compare/.nix/derivation.nix
+++ b/examples/poiseulle_particles_2d_compare/.nix/derivation.nix
@@ -1,3 +1,103 @@
{ lib
, stdenv
+, python3
}:
+
+{ pkgs ? import <nixpkgs> {} }:
+
+let
+
+ pythonEnv = python3.withPackages (ps: with ps; [
+ pandas
+ matplotlib
+ numpy
+ imageio # for video output
+ imageio-ffmpeg # ffmpeg backend for imageio
+ ]);
+
+ # The comparison & video generation script (embedded)
+ compareAndRenderPy = pkgs.writeText "compare_and_render.py" ''
+ import pandas as pd
+ import matplotlib.pyplot as plt
+ import numpy as np
+ import argparse
+ import os
+ import imageio.v2 as iio
+ from matplotlib.animation import FuncAnimation, FFMpegWriter
+
+ def main():
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--csv1', required=True)
+ parser.add_argument('--csv2', required=True)
+ parser.add_argument('--csv3', required=True)
+ parser.add_argument('--video-dir', required=True)
+ args = parser.parse_args()
+
+ df1 = pd.read_csv(args.csv1)
+ df2 = pd.read_csv(args.csv2)
+ df3 = pd.read_csv(args.csv3)
+
+ times = df1['time'].values
+ fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(10, 8))
+
+ def update(frame):
+ ax1.clear()
+ ax2.clear()
+ ax1.set_title(f'Velocity at t = {times[frame]:.2f}')
+ ax2.set_title(f'Pressure at t = {times[frame]:.2f}')
+ ax1.plot(times[:frame+1], df1['velocity'][:frame+1], label='Binary1')
+ ax1.plot(times[:frame+1], df2['velocity'][:frame+1], label='Binary2')
+ ax1.plot(times[:frame+1], df3['velocity'][:frame+1], label='Binary3')
+ ax2.plot(times[:frame+1], df1['pressure'][:frame+1], label='Binary1')
+ ax2.plot(times[:frame+1], df2['pressure'][:frame+1], label='Binary2')
+ ax2.plot(times[:frame+1], df3['pressure'][:frame+1], label='Binary3')
+ ax1.legend(), ax2.legend()
+ ax1.set_xlim(times[0], times[-1])
+ ax2.set_xlim(times[0], times[-1])
+
+ ani = FuncAnimation(fig, update, frames=len(times), repeat=False)
+ writer = FFMpegWriter(fps=5, bitrate=1800)
+ os.makedirs(args.video_dir, exist_ok=True)
+ video_path = os.path.join(args.video_dir, 'comparison.mp4')
+ ani.save(video_path, writer=writer)
+ print(f"Video saved to {video_path}")
+
+ if __name__ == '__main__':
+ main()
+ '';
+
+ # Wrapper script that runs the three binaries and then the Python comparison
+ runScript = pkgs.writeShellScript "run-simulation-pipeline" ''
+ set -e
+ mkdir -p results videos
+
+ echo "Running binary1..."
+ ${binary1}/bin/sim1
+ echo "Running binary2..."
+ ${binary2}/bin/sim2
+ echo "Running binary3..."
+ ${binary3}/bin/sim3
+
+ echo "Generating comparison video..."
+ ${pythonEnv}/bin/python ${compareAndRenderPy} \
+ --csv1 results/binary1.csv \
+ --csv2 results/binary2.csv \
+ --csv3 results/binary3.csv \
+ --video-dir videos
+
+ echo "Done. Video available at videos/comparison.mp4"
+ '';
+
+in
+pkgs.stdenv.mkDerivation {
+ name = "simulation-pipeline";
+ buildInputs = [ hlbm_2d psm_2d bgk_2d pythonEnv pkgs.ffmpeg ]; # ffmpeg for video encoding
+ buildCommand = ''
+ mkdir -p $out/bin
+ cp ${runScript} $out/bin/run-pipeline
+ chmod +x $out/bin/run-pipeline
+ # Optionally copy the Python script for reference
+ cp ${compareAndRenderPy} $out/compare_and_render.py
+ echo "Pipeline installed. Run $out/bin/run-pipeline"
+ '';
+}