{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Notebook : Modèle existant" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "from os import getcwd\n", "from pathlib import Path\n", "import sys\n", "import numpy as np\n", "\n", "# Utile pour le débogage\n", "# Besoin de pointer le répertoire de développement plutôt que le répertoire de distribution utilisé par Pypi\n", "#\n", "# Commenter la ligne suivante pour utiliser le répertoire de distribution\n", "sys.path.insert(0, str(Path('D:\\ProgrammationGitLab\\HECEPython')))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Répertoire courant" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "d:\\ProgrammationGitLab\\HECEPython\\docs\\source\\_static\\2d\n" ] } ], "source": [ "print(getcwd())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Répertoires de travail (in et out)" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Dir in : d:\\ProgrammationGitLab\\HECEPython\\docs\\source\\_static\\2d\\..\\examples\\2d\\fish_hydro\n", "Dir out: d:\\ProgrammationGitLab\\HECEPython\\docs\\source\\_static\\2d\\..\\examples\\2d\\fish_hydro\\gpu\n" ] } ], "source": [ "dir_in = Path(getcwd()) / \"../examples/2d/fish_hydro\"\n", "dir_out = dir_in / \"gpu\"\n", "\n", "print(\"Dir in :\", dir_in)\n", "print(\"Dir out:\", dir_out)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Ouverture d'une modélisation 2D CPU" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Import du module utile" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "from wolfhece.mesh2d.wolf2dprev import prev_sim2D" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Instanciation de l'objet Wolf2DModel avec passage du **répertoire et du nom générique (sans extension)** de simulation en argument (en chaîne de texte pas en objet Path)" ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [], "source": [ "\n", "mymodel = prev_sim2D(fname = str(dir_in / \"MeryCalcul\"))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Un peu d'aide sur ce que contiennent les fichiers ?" ] }, { "cell_type": "code", "execution_count": 12, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Text files\n", "----------\n", "Infiltration hydrographs [m³/s] : .fil\n", "Resulting mesh [-] : .mnap\n", "Translation to real world [m] : .trl\n", "\n", "\n", "Fine array - monoblock\n", "----------------------\n", "Mask [-] : .napbin [int16]\n", "Bed Elevation [m] : .top [float32]\n", "Bed Elevation - computed [m] : .topini_fine [float32]\n", "Roughness coefficient [law dependent] : .frot [float32]\n", "Infiltration zone [-] : .inf [int32]\n", "Initial water depth [m] : .hbin [float32]\n", "Initial discharge along X [m^2/s] : .qxbin [float32]\n", "Initial discharge along Y [m^2/s] : .qybin [float32]\n", "Rate of dissipation [m²/s³] : .epsbin [float32]\n", "Turbulent kinetic energy [m²/s²] : .kbin [float32]\n", "Z level under the deck of the bridge [m] : .bridge [float32]\n", "\n", "\n", "Multiblock arrays\n", "-----------------\n", "MB - Bed elevation [m] : .topini [float32]\n", "MB - Water depth [m] : .hbinb [float32]\n", "MB - Discharge X [m²/s] : .qxbinb [float32]\n", "MB - Discharge Y [m²/s] : .qybinb [float32]\n", "MB - Roughness coeff : .frotini [float32]\n", "MB - Rate of dissipation [m²/s³] : .epsbinb [float32]\n", "MB - Turbulent kinetic energy [m²/s²] : .kbinb [float32]\n", "\n" ] } ], "source": [ "print(mymodel.help_files())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Caractéristiques du modèle" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrices \"fines\" - non multiblocs" ] }, { "cell_type": "code", "execution_count": 14, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape : 376 x 439 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (2.0 ; 3.5) \n", " - End : (190.0 ; 223.0) \n", " - Widht x Height : 188.0 x 219.5 \n", " - Translation : (236135.0 ; 138390.0)\n", "Null value : 0.0\n", "\n", "\n" ] } ], "source": [ "myhead = mymodel.get_header()\n", "print(myhead)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Matrices multiblocs" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Shape : 376 x 439 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (2.0 ; 3.5) \n", " - End : (190.0 ; 223.0) \n", " - Widht x Height : 188.0 x 219.5 \n", " - Translation : (236135.0 ; 138390.0)\n", "Null value : 0.0\n", "\n", "Number of blocks : 6\n", "\n", "Block block1 : \n", "\n", "Shape : 376 x 439 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (0.0 ; 0.0) \n", " - End : (188.0 ; 219.5) \n", " - Widht x Height : 188.0 x 219.5 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "Block block2 : \n", "\n", "Shape : 158 x 115 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (42.5 ; 125.0) \n", " - End : (121.5 ; 182.5) \n", " - Widht x Height : 79.0 x 57.5 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "Block block3 : \n", "\n", "Shape : 8 x 8 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (45.0 ; 175.0) \n", " - End : (49.0 ; 179.0) \n", " - Widht x Height : 4.0 x 4.0 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "Block block4 : \n", "\n", "Shape : 12 x 11 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (67.0 ; 159.0) \n", " - End : (73.0 ; 164.5) \n", " - Widht x Height : 6.0 x 5.5 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "Block block5 : \n", "\n", "Shape : 12 x 11 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (85.5 ; 146.5) \n", " - End : (91.5 ; 152.0) \n", " - Widht x Height : 6.0 x 5.5 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "Block block6 : \n", "\n", "Shape : 7 x 9 \n", "Resolution : 0.5 x 0.5 \n", "Spatial extent : \n", " - Origin : (117.0 ; 127.0) \n", " - End : (120.5 ; 131.5) \n", " - Widht x Height : 3.5 x 4.5 \n", " - Translation : (236137.0 ; 138393.5)\n", "Null value : 0.0\n", "\n", "\n" ] } ], "source": [ "myheadMB = mymodel.get_header_MB()\n", "print(myheadMB)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vérifie si une simulation contient plus d'un seul bloc" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Plus qu'un bloc? : True\n", "Nombre de blocs : 6\n" ] } ], "source": [ "print(\"Plus qu'un bloc? : \", mymodel.is_multiblock)\n", "print('Nombre de blocs : ', mymodel.nb_blocks)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Vérification de l'infiltration" ] }, { "cell_type": "code", "execution_count": 17, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "inside .inf binary file\n", "-----------------------\n", "Maximum infiltration zone : 9\n", "Zone 1 : 66 cells -- Indices (i,j) of the zone's first cell (279 ; 22) (1-based)\n", "Zone 2 : 8 cells -- Indices (i,j) of the zone's first cell (43 ; 420) (1-based)\n", "Zone 3 : 8 cells -- Indices (i,j) of the zone's first cell (241 ; 253) (1-based)\n", "Zone 4 : 5 cells -- Indices (i,j) of the zone's first cell (265 ; 218) (1-based)\n", "Zone 5 : 1 cells -- Indices (i,j) of the zone's first cell (95 ; 354) (1-based)\n", "Zone 6 : 6 cells -- Indices (i,j) of the zone's first cell (138 ; 326) (1-based)\n", "Zone 7 : 6 cells -- Indices (i,j) of the zone's first cell (175 ; 301) (1-based)\n", "Zone 8 : 1 cells -- Indices (i,j) of the zone's first cell (238 ; 260) (1-based)\n", "Zone 9 : 130 cells -- Indices (i,j) of the zone's first cell (96 ; 354) (1-based)\n", "\n", "inside .fil text file\n", "----------------------\n", "Zones : 9\n", "Time steps : 2\n", "\n" ] } ], "source": [ "ret = mymodel.check_infiltration()\n", "print(ret)" ] }, { "cell_type": "code", "execution_count": 18, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "D:\\ProgrammationGitLab\\HECEPython\\wolfhece\\mesh2d\\wolf2dprev.py:8098: UserWarning: Matplotlib is currently using module://matplotlib_inline.backend_inline, which is a non-GUI backend, so cannot show the figure.\n", " fig.show()\n" ] }, { "data": { "text/plain": [ "(
, )" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" }, { "data": { "image/png": "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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "mymodel.infiltration.plot_plt()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Récupération d'un fichier particulier" ] }, { "cell_type": "code", "execution_count": 19, "metadata": {}, "outputs": [], "source": [ "top = mymodel.read_fine_array(which = '.top')\n", "h = mymodel.read_fine_array(which = '.hbin')\n", "qx = mymodel.read_fine_array(which = '.qxbin')\n", "qy = mymodel.read_fine_array(which = '.qybin')\n", "inf = mymodel.read_fine_array(which = '.inf')\n", "frott = mymodel.read_fine_array(which = '.frot')\n", "\n", "all_data = [top, h, qx, qy, inf, frott]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Chaque variable est de type \"WolfArray\"..." ] }, { "cell_type": "code", "execution_count": 20, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n", "\n", "\n", "\n", "\n" ] } ], "source": [ "for cur in all_data:\n", " print(type(cur))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Manipulation de données" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "La matrice est stockée dans l'attribut \"array\" de chaque objet.\n", "\n", "Il s'agit d'une matrice masquée --> voir module numpy.ma au besoin : https://numpy.org/doc/stable/reference/maskedarray.generic.html" ] }, { "cell_type": "code", "execution_count": 21, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n" ] } ], "source": [ "np_ma_top = top.array\n", "print(type(np_ma_top))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Une matrice Numpy \"sans masque\" peut être obtenue sur base de l'attribut data ou en faisant une copie.\n", "\n", "ATTENTION aux effets de partage ou pas de la mémoire..." ] }, { "cell_type": "code", "execution_count": 22, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "\n", "\n" ] } ], "source": [ "np_top = top.array.data\n", "print(type(np_top))\n", "\n", "np_top2 = top.array.data.copy()\n", "print(type(np_top2))\n", "\n", "np_top[1,1] = -1\n", "assert(np_top[1,1] == top.array.data[1,1]), \"Memory share --> same value in data\"\n", "\n", "np_top2[1,1] = -2\n", "assert(np_top2[1,1] != top.array.data[1,1]), \"Memory copy --> different value in data\"\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Typage\n", "\n", "Toutes les matrices ne contiennent pas nécessairement les mêmes **types** de données\n", "\n", "- Float32 --> 4 octets par valeur\n", "- Int32 --> 4 octets par valeur\n", "- Int16 --> 2 octets par valeur" ] }, { "cell_type": "code", "execution_count": 23, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "float32\n", "float32\n", "float32\n", "float32\n", "int32\n", "float32\n" ] } ], "source": [ "for cur in all_data:\n", " print(cur.array.dtype)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Recopiage des matrices fines pour une simulation GPU" ] }, { "cell_type": "code", "execution_count": 24, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ ".inf --> infiltration_zones.npy [np.int32]\n", ".frot --> manning.npy [np.float32]\n", ".hbin --> h.npy [np.float32]\n", ".qxbin --> qx.npy [np.float32]\n", ".qybin --> qy.npy [np.float32]\n", ".napbin --> nap.npy [np.uint8]\n", ".top --> bathymetry.npy [np.float32]\n", "Force a value 99999. outside nap\n", "\n", "52831 active cells in bathymetry.npy\n", "All files copied successfully\n" ] } ], "source": [ "ret = mymodel.copy2gpu(dir_out)\n", "print(ret)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Vérification du type" ] }, { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [], "source": [ "gpufiles = [('bathymetry.npy', np.float32),\n", " ('manning.npy' , np.float32),\n", " ('h.npy', np.float32),\n", " ('qx.npy', np.float32),\n", " ('qy.npy', np.float32),\n", " ('infiltration_zones.npy', np.int32),\n", " ('nap.npy', np.uint8)\n", " ]\n", "\n", "for curfile, curtype in gpufiles:\n", " cur:np.ndarray = np.load(dir_out / curfile)\n", " assert cur.dtype == curtype, f\"Type mismatch for {curfile} : {cur.dtype} != {curtype}\"" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Il reste à ...\n", " \n", "- créer une simulation GPU sur base des fichiers recopiés\n", "- paramétrer la simulation GPU avec :\n", " - des conditions aux imites ad-hoc\n", " - des débits d'infiltration/exfiltration\n", " - le mode de calcul\n", " - ...\n", "\n", "**A vous de jouer !**\n" ] } ], "metadata": { "kernelspec": { "display_name": "python3.10", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.11" } }, "nbformat": 4, "nbformat_minor": 2 }