1
Fork 0

Merge branch 'master' of ssh://git.edgarpierre.fr:39529/m2cce/internship

This commit is contained in:
Edgar P. Burkhart 2023-05-16 11:56:12 +02:00
commit 166331cd31
Signed by: edpibu
GPG key ID: 9833D3C5A25BD227
6 changed files with 98 additions and 260 deletions

View file

@ -5,6 +5,16 @@ données.
## Scripts
### Run Olaflow
`run_ola.sh` permet de lancer les scripts Python et openfoam nécessaires au bon lancement du modèle Olaflow.
```./run_ola.sh CASE```
* `CASE` : choix du modèle Olaflow à utiliser
Le cas de base utilisé est dans le dossier `of`. Les fichiers modifiés sont dans le dossier `of_$CASE`. Les sorties
sont dans `out_of_$CASE` puis `out_post_$CASE`.
### Animate
`animate.py` permet d'obtenir une animation de `alpha.water` et `U` en sortie du modèle Olaflow.
@ -67,3 +77,55 @@ d'enregistrer cet objet pour une utilisation efficace avec Python.
* `-i INPUT` : dossier de sortie d'Olaflow
* `-o OUTPUT` : dossier de sortie à utiliser
* `-z` : activer la compression gzip (déconseillé)
### STL
`stl.py` définit une fonction permettant de convertir un tableau de bathymétrie en fichier STL. Nécessite Openscad.
### SWS Olaflow
`sws_ola.py` permet de convertir les données de sortie d'un modèle Swash en condition initiale d'un modèle Olaflow.
```python -m processing.sws_ola -o OUTPUT [-c CONFIG]```
* `-o OUTPUT` : dossier de sortie à utiliser
* `-c CONFIG` : choix d'un fichier de configuration
```
[swash]
np_out : dossier de sortie swash
[bathy]
level : niveau d'eau dans SWASH
[olaflow]
t0 : instant initial du modèle Olaflow
```
### SWS Wavedict Irregular
`sws_wavedict_irregular.py` est une tentative de convertir les données de sortie d'un modèle SWASH en condition limite
irrégulière de spectre d'un modèle Olaflow. Ne fonctionne pas.
### SWS Wavedict Paddle
`sws_wavedict_paddle.py` permet de convertir les données de sortie d'un modèle SWASH en condition limite en hauteur
d'eau et vitesse d'un modèle Olaflow.
```python -m processing.sws_wavedict_paddle -o OUTPUT [-c CONFIG]```
* `-o OUTPUT` : dossier de sortie à utiliser
* `-c CONFIG` : choix d'un fichier de configuration
```
[swash]
np_out : dossier de sortie swash
[bathy]
level : niveau d'eau dans SWASH
[olaflow]
t0 : instant initial du modèle Olaflow
tf : instant final du modèle Olaflow
x0 : position de la limite du modèle Olaflow
```

View file

@ -1,90 +0,0 @@
import argparse
import configparser
import gzip
from itertools import starmap
import logging
import multiprocessing as mp
import pathlib
import pickle
from cycler import cycler
import matplotlib.pyplot as plt
import matplotlib.gridspec as gridspec
import numpy as np
from scipy import interpolate
from .olaflow import OFModel
parser = argparse.ArgumentParser(description="Post-process olaflow results")
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument("-c", "--config", default="config.ini")
args = parser.parse_args()
logging.basicConfig(level=max((10, 20 - 10 * args.verbose)))
log = logging.getLogger("ola_post")
log.info("Animating olaFlow output")
config = configparser.ConfigParser()
config.read(args.config)
out = pathlib.Path(config.get("post", "out"))
out.mkdir(parents=True, exist_ok=True)
with (
path.open("rb")
if (path := out.joinpath("pickle")).exists()
else gzip.open(path.with_suffix(".gz"), "rb")
) as f:
model = pickle.load(f)
x0_conf = config.getfloat("post", "x")
x0_val = model.x[np.argmin(np.abs(model.x - x0_conf))]
# z0 = config.getfloat("post", "z")
# z0 = np.linspace(-5, 5, 16)
c0_ = ((model.x == x0_val)[None, :] & (model.fields["alpha.water"] > 0.95)).any(axis=0)
c0 = model.coords[c0_][:: (c0_.sum() // 8 + 1)]
i0 = np.argmin(
np.linalg.norm(model.coords[..., None] - c0.T[None, ...], axis=1),
axis=0,
)
aw = model.fields["alpha.water"][:, i0]
U = np.where(aw > 0.95, np.linalg.norm(model.fields["U"][..., i0], axis=1), np.nan)
P = np.where(aw > 0.95, model.fields["p"][..., i0], np.nan)
P_rgh = np.where(aw > 0.95, model.fields["p_rgh"][..., i0], np.nan)
with plt.rc_context(
{
"axes.prop_cycle": cycler(
color=np.linspace(0, 1, i0.size + 1)[:-1].astype("U")
),
"axes.grid": True,
"axes.xmargin": 0,
}
):
fig, ax = plt.subplots(3, constrained_layout=True)
ax1, ax2, ax3 = ax
ha = ax1.plot(model.t, U, lw=1)
ax1.set(xlabel="t (s)", ylabel="U (m/s)")
ax2.plot(model.t, P * 1e-3, lw=1)
ax2.set(xlabel="t (s)", ylabel="P (kPa)")
ax3.plot(model.t, P_rgh * 1e-3, lw=1)
ax3.set(xlabel="t (s)", ylabel="P_rgh (kPa)")
for a in ax:
a.set(ylim=0)
ax2.legend(
ha,
list(
starmap(lambda x, z: f"x={x:8}m; z={z:8}m", zip(model.x[i0], model.z[i0]))
),
bbox_to_anchor=(1.05, 0.5),
loc="center left",
)
fig.savefig(out.joinpath("fig.pdf"))

View file

@ -1,79 +0,0 @@
import argparse
import gzip
import logging
import multiprocessing as mp
import pathlib
import pickle
import matplotlib.pyplot as plt
import matplotlib.animation as animation
from matplotlib.gridspec import GridSpec
from matplotlib.ticker import MultipleLocator
import numpy as np
from scipy import interpolate
from .olaflow import OFModel
parser = argparse.ArgumentParser(description="Post-process olaflow results")
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument(
"-o",
"--output",
type=pathlib.Path,
help="Output directory for pickled data",
required=True,
)
parser.add_argument(
"-m",
"--max",
help="Only compute maximum rather than animation",
action="store_true",
)
parser.add_argument(
"-i",
"--initial",
help="Only compute initial domain",
action="store_true",
)
args = parser.parse_args()
logging.basicConfig(level=max((10, 20 - 10 * args.verbose)))
log = logging.getLogger("ola_post")
log.info("Animating olaFlow output")
out = args.output
out.mkdir(parents=True, exist_ok=True)
with (
path.open("rb")
if (path := out.joinpath("pickle")).exists()
else gzip.open(path.with_suffix(".gz"), "rb")
) as f:
model = pickle.load(f)
x0, idx0 = np.unique(model.x.astype(np.half), return_inverse=True)
z0, idz0 = np.unique(model.z.astype(np.half), return_inverse=True)
ix0 = np.argsort(x0)
iz0 = np.argsort(z0)[::-1]
X, Z = np.meshgrid(x0, z0)
P = np.full((model.t.size, *X.shape), np.nan)
P[:, iz0[idz0], ix0[idx0]] = model.fields["porosity"]
AW = np.full((model.t.size, *X.shape), np.nan)
AW[:, iz0[idz0], ix0[idx0]] = model.fields["alpha.water"]
#U = np.full((model.t.size, *X.shape), np.nan)
#U[:, iz0[idz0], ix0[idx0]] = np.linalg.norm(model.fields["U"], axis=1)
i0 = np.argmin(np.abs(model.t[:, None] - np.asarray((102, 118, 144.5, 176.5))[None, :]), axis=0)
fig, ax_ = plt.subplots(
2, 2, figsize=(15 / 2.54, 4 / 2.54), dpi=200, constrained_layout=True
)
for ax, i in zip(ax_.flatten(), i0):
ax.imshow(AW[i], cmap="Blues", vmin=0, vmax=1)
fig.savefig(out.joinpath("snap.pdf"))

36
swash/README.md Normal file
View file

@ -0,0 +1,36 @@
# SWASH
Ce dossier regroupe l'ensemble des scripts nécessaires à l'éxécution du modèle SWASH ainsi qu'au post-traitement des
données.
## Scripts
### Animate
`animate.py` permet d'obtenir une animation des résultats de SWASH.
```python -m processing.animate [-c CONFIG]```
* `-c CONFIG` : choix du fichier de configuration
```
[post]
inp : dossier contenant les données d'entrée
out : dossier de sortie
```
### Mat Npz
`mat_npz` permet de convertir les données de sortie de SWASH en données Numpy plus facile à exploiter en Python.
```python -m processing.mat_npz [-c CONFIG]```
* `-c CONFIG` : choix du fichier de configuration
```
[swash]
out : dossier de sortie de swash
[post]
inp : dossier de sortie pour les données numpy
```

View file

@ -20,7 +20,6 @@ config = configparser.ConfigParser()
config.read(args.config)
inp = pathlib.Path(config.get("post", "inp"))
root = pathlib.Path(config.get("swash", "out"))
out = pathlib.Path(config.get("post", "out"))
out.mkdir(parents=True, exist_ok=True)

View file

@ -1,90 +0,0 @@
import argparse
import configparser
import logging
import pathlib
import matplotlib.animation as animation
import matplotlib.pyplot as plt
import numpy as np
parser = argparse.ArgumentParser(description="Animate swash output")
parser.add_argument("-v", "--verbose", action="count", default=0)
parser.add_argument("-c", "--config", default="config.ini")
args = parser.parse_args()
logging.basicConfig(level=max((10, 20 - 10 * args.verbose)))
log = logging.getLogger("post")
log.info("Starting post-processing")
config = configparser.ConfigParser()
config.read(args.config)
inp = pathlib.Path(config.get("post", "inp"))
root = pathlib.Path(config.get("swash", "out"))
out = pathlib.Path(config.get("post", "out"))
out.mkdir(parents=True, exist_ok=True)
def data(var):
return np.load(inp.joinpath(f"{var}.npy"))
x = data("xp")
t = data("tsec")
watl = data("watl")
botl = data("botl")
zk = data("zk")
velk = data("velk")
vz = data("vz")
wl = np.maximum(watl, -botl)
# print(x.size, -np.arange(0, 1 * bathy.hstru.size, 1)[::-1].size)
fig, ax = plt.subplots()
# ax.plot(x, -botl, c="k")
# ax.fill_between(
# x, -botl, -data["botl"] + bathy.hstru, color="k", alpha=0.2
# )
n = 0
vk = np.sqrt((velk[n] ** 2).sum(axis=1))
# print(vk.shape)
# plt.imshow(vk)
# plt.colorbar()
lines = ax.plot(x, zk[n].T, c="#0066cc")
quiv = []
for i in range(len(lines) - 1):
quiv.append(
ax.quiver(
x[::50],
(zk[n, i, ::50] + zk[n, i + 1, ::50]) / 2,
velk[n, i, 0, ::50],
vz[n, i, ::50],
units="dots",
width=2,
scale=0.05,
)
)
ax.autoscale(True, "w", True)
ax.set_ylim(top=15)
def animate(k):
for i, q in enumerate(quiv):
q.set_UVC(
velk[k, i, 0, ::50],
vz[k, i, ::50],
)
for i, l in enumerate(lines):
l.set_ydata(zk[k, i])
return *quiv, *lines
ani = animation.FuncAnimation(
fig, animate, frames=wl[:, 0].size, interval=20, blit=True
)
ani.save(out.joinpath("layers.mp4"))