{ "cells": [ { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Application (Preccinsta Combustion Chamber)\n", "## Post-processing of a CFD simulation with an unstructured multi-element dataset.\n", "\n", "This tutorial will help you build a post-processing on the Preccinsta test case. Please download the associated data at https://www.cerfacs.fr/antares/downloads/application2_tutorial_data.tgz\n", "\n", "untar the archive in the working directory\n", "\n", "copy the app2_combustion.ipynb in the directory application2" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Preliminary steps\n", "\n", "import os, numpy, and antares packages\n", "\n", "create a directory named OUTPUT" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "fragment" } }, "outputs": [], "source": [ "import \n", "\n", "import \n", "\n", "import \n", "\n", "if :\n", " os." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Part I: Read Input Data\n", "\n", "The first step is to create a base from the data of a CFD simulation of the Preccinsta combustion chamber. This data structure will be used in the following post-processing. \n", "\n", "The first step is to create a Base named base by reading the grid from files MESH/mesh.mesh.h5 (hdf_avbp format) as shared data. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "reader = antares.\n", "reader[] = os.path.join()\n", "reader[] = \n", "base = " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Now add to your existing base the solution stored in the file SOLUT/sol_ite0001000.h5 (hdf_avbp format). " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "reader = antares.\n", "reader[] = \n", "reader[] = os.path.join()\n", "reader." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Part II: Extract Skin Data\n", "\n", "This part details the steps to extract the skin of the combustion chamber.\n", " \n", "To extract the walls of the Preccinsta combustion chamber, create a Base skin_base from the Family Patches which contains the boundaries of your simulation." ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "print(base.families)\n", "\n", "skin_base = " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "To remove the atmospheric boundaries and only keep the combustion chamber wall, use the threshold treatment (see documentation to know how it works) to create a Base thres_skin_base that contains the cells matching the following conditions:\n", "\n", " x < 0.11\n", " -0.045 < y < 0.045\n", " -0.045 < z < 0.\n", "\n", "Printing the grid_points attribute of the resulting Base object shows that the size of the extracted dataset is much smaller.\n" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "clip = antares.\n", "clip[] = \n", "clip[] = \n", "clip[] = \n", "clip_skin_base = " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Finally, to visualize the extracted skin data, write the base thres_skin_base in VTK binary format (compatible with Paraview software) in the directory OUTPUT/SKIN/. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "writer = antares.\n", "writer[] = \n", "writer[] = os.path.join()\n", "writer." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Part III: Create Cut\n", "\n", "This part will teach you how to extract the tangential velocity on an transversal geometrical cut. \n", "\n", "We want to visualize the tangential velocity on a geometrical cut. First, to reduce the size of the dataset, remove the atmospheric domain by keeping only the cells matching the following conditions:\n", "\n", " x < 0.11\n", " -0.045 < y < 0.045\n", " -0.045 < z < 0.045\n", "\n", "The base obtained after the threshold will be named thres_base. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "clip = antares.\n", "clip[] = \n", "clip[] = \n", "clip[] = \n", "clip_base = \n", "\n", "print(clip_base.grid_points)" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Use the cut treatment (see documentation for more information) to perform a geometrical plane cut in your domain at a constant z value of 0. The base obtained after cut will be named cut_base. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "plane_cut = antares.\n", "plane_cut[] = \n", "plane_cut[] = \n", "plane_cut[] = \n", "plane_cut[] = \n", "cut_base = " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Use the function compute() to compute the tangential velocity (the velocity minus the axial contribution) on your base.\n", "To finally visualize the cut, write the base cut_base in VTK binary format (compatible with Paraview software) in directory OUTPUT/ZCUT/. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "cut_base.\n", "cut_base.\n", "\n", "writer = antares.\n", "writer[] = \n", "writer[] = os.path.join()\n", "writer." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Part IV: Plot Data Over Line\n", "\n", "The objective of this part is to plot the Mach number distribution along the y-axis at the swirler outlet. \n", "\n", "We want now to vizualize Mach number distribution along the line at x = 0.005 and z = 0.0. So first, use the cut treatment on the cut_base (from part III) to perform a cut at x = 0.005. Then use the merge treatment (see documentation to learn how it works) to merge and the unwrapline treatment to reorganize the line points. The base obtained will be named line_base. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "plane_cut = antares.Treatment()\n", "plane_cut[] = \n", "plane_cut[] = \n", "plane_cut[] = \n", "plane_cut[] = \n", "line_base =\n", "\n", "merge = antares.\n", "merge[] = \n", "merge[] = \n", "line_base1 = \n", "\n", "unw = antares.\n", "unw[] = \n", "unw[] = \n", "line_base = " ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "To visualize data stored in the base line_base use matplotlib. Plot the Mach number distribution versus y. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "import matplotlib.pyplot as plt\n", "plt.plot(line_base[0][0]['y'], line_base[0][0]['Mach'],lw=2.5)\n", "plt.grid()\n", "plt.xlabel('{}'.format('y'), fontsize=18)\n", "plt.ylabel('{}'.format('Mach'), fontsize=18)\n", "plt.autoscale(axis='x')\n", "plt.autoscale(axis='y')\n", "plt.show()\n", "plt.close()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "Write the base line_base in directory OUTPUT/LINE/ in the column format. " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "writer = antares.\n", "writer[] = \n", "writer[] = os.path.join()\n", "writer.dump()" ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "slide" } }, "source": [ "# Part V: Compute Average Quantities\n", "\n", "Finally, it can be interesting to compute the average thickening and efficiency over the flame front. In fact it allows to evaluate the quality of your simulation relatively to grid refinement and flame front resolution. \n", "\n", "As we want to compute the average thickening and efficiency over the flame front, the first step is to extract this flame front data from the 3D dataset. It can be assimilated to the isosurface of temperature 1500 Kelvin. To do so, use the isosurface treatment to create the base iso_base from clip_base (from part III). " ] }, { "cell_type": "code", "execution_count": null, "metadata": { "slideshow": { "slide_type": "subslide" } }, "outputs": [], "source": [ "iso = antares.\n", "iso[] = \n", "iso[] = \n", "iso[] = \n", "iso_base = \n", "\n", "writer = antares.\n", "writer[] = \n", "writer[] = os.path.join()\n", "writer." ] }, { "cell_type": "markdown", "metadata": { "slideshow": { "slide_type": "subslide" } }, "source": [ "To compute surface averages, we need to know the cell surfaces. see Base method compute_cell_normal(). \n", "\n", "Now that the variable 'surface' is available in the base, use it to compute the product of Efficiency and Thickening and surface (needed for surface averaging) \n", "\n", " Finally use the numpy function sum() to integrate data and compute the average efficiency and thickening. " ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "t = antares.\n", "t[] = \n", "integral_base = \n", "\n", "effic = integral_base[0][0]['Efficiency'][0]\n", "thick = integral_base[0][0]['Thickening'][0]\n", "surface = integral_base[0][0]['volume'][0]\n", "\n", "effic /= surface\n", "thick /= surface\n", "\n", "print('\\n >>> Isosurface average :')\n", "print(' - Efficiency : {:.2f}'.format(effic))\n", "print(' - Thickening : {:.2f}'.format(thick))\n", "# >>> Isosurface average :\n", "# - Efficiency : 3.55\n", "# - Thickening : 11.62" ] } ], "metadata": { "celltoolbar": "Diaporama", "kernelspec": { "display_name": "Python 3", "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.8.5" }, "nbpresent": { "slides": { "046854bb-a4d0-4839-a656-3c29bfa2eafa": { "id": "046854bb-a4d0-4839-a656-3c29bfa2eafa", "prev": "84edf4c4-5c79-4186-a419-f1a524255c47", "regions": { "bcfe2215-71a6-4f03-bc3a-cf45c2756ec8": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "e1b15d2c-795f-406d-8130-b73f190da8ca", "part": "whole" }, "id": "bcfe2215-71a6-4f03-bc3a-cf45c2756ec8" } } }, "21beb54a-dbf4-4372-b741-72f75c45488b": { "id": "21beb54a-dbf4-4372-b741-72f75c45488b", "prev": "c5f9ef9c-fda9-4f64-81b0-8df95ac9a0e7", "regions": { "322dbed9-3442-4b1a-82cd-4322d9af373e": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "60bef50c-9fe4-4d42-a3b3-16dee2c569d4", "part": "whole" }, "id": "322dbed9-3442-4b1a-82cd-4322d9af373e" } } }, "31895f0d-c84f-48fd-9e46-3910f3a32871": { "id": "31895f0d-c84f-48fd-9e46-3910f3a32871", "prev": null, "regions": { "255b4f54-02eb-4c41-bf69-c668d8117399": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "3e2abaca-ff6d-4475-97f6-b43d1634e2c9", "part": "source" }, "id": "255b4f54-02eb-4c41-bf69-c668d8117399" } } }, "4090087b-dded-4a9e-a828-8f208228d474": { "id": "4090087b-dded-4a9e-a828-8f208228d474", "prev": "046854bb-a4d0-4839-a656-3c29bfa2eafa", "regions": { "e367bf97-6261-4623-b7dd-1694ad126099": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "42947e78-728f-4008-bd3d-d1f0110164a1", "part": "whole" }, "id": "e367bf97-6261-4623-b7dd-1694ad126099" } } }, "84edf4c4-5c79-4186-a419-f1a524255c47": { "id": "84edf4c4-5c79-4186-a419-f1a524255c47", "prev": "a209d110-660b-4251-a92e-e4d7a7e2f95d", "regions": { "e10c5d08-4e24-4045-a27d-d6901a4df427": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "e3738ad3-06a7-4974-873b-6385ed7f8b30", "part": "source" }, "id": "e10c5d08-4e24-4045-a27d-d6901a4df427" } } }, "a209d110-660b-4251-a92e-e4d7a7e2f95d": { "id": "a209d110-660b-4251-a92e-e4d7a7e2f95d", "prev": "31895f0d-c84f-48fd-9e46-3910f3a32871", "regions": { "50d5c9c8-cca1-4f70-b2b1-97961e71d2d3": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "1a128849-789e-4bad-8366-d5b57675e4d2", "part": "source" }, "id": "50d5c9c8-cca1-4f70-b2b1-97961e71d2d3" } } }, "c5f9ef9c-fda9-4f64-81b0-8df95ac9a0e7": { "id": "c5f9ef9c-fda9-4f64-81b0-8df95ac9a0e7", "prev": "4090087b-dded-4a9e-a828-8f208228d474", "regions": { "e4cbbebb-636e-4ef0-82ef-950cd5adb8af": { "attrs": { "height": 0.8, "width": 0.8, "x": 0.1, "y": 0.1 }, "content": { "cell": "73689d5a-c0db-4e1d-a0d6-16021b427eea", "part": "whole" }, "id": "e4cbbebb-636e-4ef0-82ef-950cd5adb8af" } } } }, "themes": {} } }, "nbformat": 4, "nbformat_minor": 2 }