From 2503e8dfae867c95667887462c7f80d03817f1e3 Mon Sep 17 00:00:00 2001
From: "Edgar P. Burkhart" <git@edgarpierre.fr>
Date: Sun, 23 Jan 2022 09:38:00 +0100
Subject: [PATCH] Animation generator

---
 post_process/animate/__main__.py    |  17 ++++
 post_process/animate/alpha_water.py | 115 ++++++++++++++++++++++++++++
 post_process/config.ini             |   6 ++
 3 files changed, 138 insertions(+)
 create mode 100644 post_process/animate/__main__.py
 create mode 100644 post_process/animate/alpha_water.py
 create mode 100644 post_process/config.ini

diff --git a/post_process/animate/__main__.py b/post_process/animate/__main__.py
new file mode 100644
index 0000000..12695ba
--- /dev/null
+++ b/post_process/animate/__main__.py
@@ -0,0 +1,17 @@
+import argparse
+
+parser = argparse.ArgumentParser(
+    description='Animate the results from OpenFoam'
+)
+parser.add_argument('var', type=str,
+    help='OpenFoam variable to display')
+parser.add_argument('-c', '--config', type=str,
+    help='Configuration file')
+
+args = parser.parse_args()
+if args.config == None:
+    args.config = 'config.ini'
+
+if args.var == 'alpha.water':
+    import alpha_water
+    alpha_water.animate(args.config)
diff --git a/post_process/animate/alpha_water.py b/post_process/animate/alpha_water.py
new file mode 100644
index 0000000..7ffb016
--- /dev/null
+++ b/post_process/animate/alpha_water.py
@@ -0,0 +1,115 @@
+from pathlib import Path
+import re
+from multiprocessing.pool import ThreadPool 
+from pprint import pp
+from time import time
+import logging
+import configparser
+from contextlib import redirect_stdout
+from io import StringIO
+
+import matplotlib as mpl
+import matplotlib.pyplot as plt
+from matplotlib import cm
+from matplotlib import patches
+import matplotlib.animation as animation
+from scipy.interpolate import griddata
+import numpy as np
+import pandas as pd
+
+mpl.use('agg')
+
+import fluidfoam
+#import stl
+
+def animate(config_path):
+    tt0 = time()
+    
+    config = configparser.ConfigParser()
+    config.read(config_path)
+
+    log = logging.getLogger('alpha_water')
+    logging.basicConfig(encoding='utf-8', level=config['main']['logging'])
+    log.info('Starting')
+    
+    root = Path(config['main']['root'])
+    
+    t = []
+    
+    log.info(f'Finding timesteps in {root}')
+    for item in root.iterdir():
+      if item.is_dir() and re.match(r'^[0-9]+(\.[0-9]+)?$', item.name):
+        t.append(item.name)
+    
+    timesteps = pd.Series(t, dtype='string', name='t')
+    
+    log.info('Reading mesh')
+    fluidfoam_log = StringIO()
+    with redirect_stdout(fluidfoam_log):
+        mesh = fluidfoam.readmesh(str(root))
+    log.info('Reading alpha.water for each time step')
+    with ThreadPool(4) as pool:
+      with redirect_stdout(fluidfoam_log):
+        aw = zip(timesteps, pool.map(
+            lambda t:fluidfoam.readscalar(root, t, 'alpha.water'), timesteps))
+    
+    log.info('Building alpha_water')
+    alpha_water = pd.DataFrame(dict(aw)).round(2)
+    del aw
+    
+    alpha_water['x'] = mesh[0]
+    alpha_water['y'] = mesh[2]
+    
+    bathy = pd.read_hdf(
+        config['bathy']['path'],
+        'bathy',
+    )
+    
+    log.info('Starting plot')
+    fig, ax = plt.subplots(figsize=(19.2,10.8), dpi=100)
+    
+    base_artists = [
+        ax.fill_between(
+            bathy.index,
+            bathy,
+            np.floor(bathy.min()/10)*10,
+            color='k',
+            zorder=10
+        ),
+    ]
+    
+    log.info('Generating artists')
+    with ThreadPool(4) as pool:
+        ims = pool.map(
+            lambda t:ax.tricontourf(
+                alpha_water.x,
+                alpha_water.y,
+                alpha_water[t],
+                cmap=cm.Blues,
+                levels=[0.1,0.9],
+                vmin=0, vmax=1,
+                zorder=1,
+                extend='both'
+            ),
+            timesteps
+        )
+    
+    ax.set(
+        aspect='equal',
+        xlim=(alpha_water.x.min(), alpha_water.x.max()),
+        ylim=alpha_water.y.min()
+    )
+    fig.colorbar(ims[-1], orientation='horizontal')
+    fig.tight_layout()
+    
+    log.info('Generating animation')
+    ani = animation.ArtistAnimation(
+        fig,
+        [im.collections for im in ims],
+        interval=1000/10,
+        blit=True,
+        repeat=True
+    )
+    ani.save('anim.mp4')
+    
+    log.info('Program ended successfully')
diff --git a/post_process/config.ini b/post_process/config.ini
new file mode 100644
index 0000000..a81ec51
--- /dev/null
+++ b/post_process/config.ini
@@ -0,0 +1,6 @@
+[main]
+logging = INFO
+root = /home/masterccce/OpenFOAM/work/artha
+
+[bathy]
+path = ../bathymetry/3_pd/data.hdf
