2022-01-23 09:38:00 +01:00
|
|
|
from pathlib import Path
|
|
|
|
import re
|
|
|
|
from multiprocessing.pool import ThreadPool
|
|
|
|
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
|
|
|
|
|
2022-01-23 14:34:55 +01:00
|
|
|
def animate(config_path, log_level):
|
2022-01-23 09:38:00 +01:00
|
|
|
tt0 = time()
|
|
|
|
|
|
|
|
config = configparser.ConfigParser()
|
|
|
|
config.read(config_path)
|
|
|
|
|
2022-01-23 14:34:55 +01:00
|
|
|
logging.basicConfig(
|
|
|
|
filename=config.get('main', 'log_file', fallback=None),
|
|
|
|
level=log_level
|
|
|
|
)
|
2022-01-23 09:38:00 +01:00
|
|
|
log = logging.getLogger('alpha_water')
|
|
|
|
log.info('Starting')
|
|
|
|
|
2022-01-23 14:34:55 +01:00
|
|
|
root = Path(config.get('main', 'root')).expanduser()
|
2022-01-23 09:38:00 +01:00
|
|
|
|
|
|
|
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)
|
|
|
|
|
2022-01-23 10:04:30 +01:00
|
|
|
timesteps = pd.Series(t, dtype='string', name='t')\
|
|
|
|
.sort_values(key=np.float64)
|
2022-01-23 09:38:00 +01:00
|
|
|
|
|
|
|
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]
|
|
|
|
|
2022-01-23 10:04:30 +01:00
|
|
|
with pd.HDFStore(
|
2022-01-23 14:34:55 +01:00
|
|
|
config.get('data', 'path'),
|
2022-01-23 10:04:30 +01:00
|
|
|
mode='r',
|
|
|
|
) as hdf:
|
|
|
|
bathy = hdf.get('bathy')
|
|
|
|
rubble = hdf.get('rubble')
|
|
|
|
blocs = {}
|
2022-01-23 14:34:55 +01:00
|
|
|
for bloc in config.get('data', 'blocs', fallback='').split(','):
|
2022-01-23 10:04:30 +01:00
|
|
|
blocs[bloc] = hdf.get(bloc)
|
2022-01-23 09:38:00 +01:00
|
|
|
|
|
|
|
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
|
|
|
|
),
|
2022-01-23 10:04:30 +01:00
|
|
|
ax.fill_between(
|
|
|
|
rubble.index,
|
|
|
|
rubble,
|
|
|
|
rubble.min(),
|
|
|
|
color='k',
|
|
|
|
alpha=.1,
|
|
|
|
lw=2,
|
|
|
|
zorder=11
|
|
|
|
),
|
|
|
|
*[
|
|
|
|
ax.fill(
|
2022-01-23 10:31:18 +01:00
|
|
|
a.index.values,
|
|
|
|
a.values,
|
2022-01-23 10:04:30 +01:00
|
|
|
color='k',
|
|
|
|
zorder=12
|
2022-01-23 10:31:18 +01:00
|
|
|
) for a in blocs.values()
|
2022-01-23 10:04:30 +01:00
|
|
|
]
|
2022-01-23 09:38:00 +01:00
|
|
|
]
|
|
|
|
|
|
|
|
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
|
|
|
|
)
|
2022-01-23 14:34:55 +01:00
|
|
|
ani.save(config.get('main', 'out'))
|
2022-01-23 09:38:00 +01:00
|
|
|
|
|
|
|
log.info('Program ended successfully')
|