{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "a8e59e9a",
   "metadata": {},
   "source": [
    "# Ejercicio parte 3 : Modelo conceptual"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "9c7f15bd",
   "metadata": {},
   "source": [
    "Para este tutorial vamos a simular un flujo permanente de recarga, evapotranspiración y drenaje en una cuenca. Identificaremos zonas de recargar y de descarga.\n",
    "\n",
    "EL acuífero de la cuenca es modelado con 5 estratos, los dos primeros son no acuíferos no confinados y los 3 últimos confinados. \n",
    "\n",
    "La tasa de evapotranspiración: 3.8 10^(-8) m/s \n",
    "\n",
    "Tasa de recarga: 4.7 10^(-9) m/s\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "b9cc7e15",
   "metadata": {},
   "outputs": [],
   "source": [
    "import warnings\n",
    "warnings.filterwarnings('ignore')\n",
    "\n",
    "from scipy.interpolate import griddata\n",
    "from osgeo import osr\n",
    "from osgeo import gdal\n",
    "from osgeo import gdal_array\n",
    "import rasterio\n",
    "from rasterio.transform import from_origin\n",
    "import geopandas as gpd\n",
    "\n",
    "from shapely.geometry import mapping\n",
    "from shapely.geometry import Polygon, Point, MultiLineString\n",
    "from collections import OrderedDict\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "#plots\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "#modflow\n",
    "import flopy\n",
    "import flopy.discretization as fgrid\n",
    "import flopy.plot as fplot\n",
    "from flopy.utils.gridintersect import GridIntersect\n",
    "import flopy.utils.binaryfile as bf\n",
    "\n",
    "import os, json\n",
    "\n",
    "import sys\n",
    "sys.path.insert(0, '../src')\n",
    "from meshProperties import mesh_shape"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "ca2ce47d",
   "metadata": {},
   "source": [
    "# Propiedades DISV"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "b3d338b6",
   "metadata": {},
   "outputs": [],
   "source": [
    "f=open('../examples/out/angascancha/json/disvDict.json')\n",
    "gridprops = json.load(f)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "0a90a2b0",
   "metadata": {},
   "outputs": [],
   "source": [
    "cell2d = gridprops['cell2d']\n",
    "vertices = gridprops['vertices']\n",
    "ncpl = gridprops['ncpl']\n",
    "nvert = gridprops['nvert']\n",
    "centroids=[(x[0],x[1]) for x in gridprops['centroids']]"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7c7c598f",
   "metadata": {},
   "source": [
    "# Geometria del Acuifero"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "d5d0c925",
   "metadata": {},
   "outputs": [],
   "source": [
    "#Extact dem values for each centroid of the voronois\n",
    "src = rasterio.open('../examples/in/rst/DEM_200b.tif')\n",
    "elevation=[x for x in src.sample(centroids)]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "e986f4e6",
   "metadata": {},
   "outputs": [],
   "source": [
    "nlay = 5\n",
    "\n",
    "mtop=np.array([elev[0] for i,elev in enumerate(elevation)])\n",
    "zbot=np.zeros((nlay,ncpl))\n",
    "\n",
    "\n",
    "AcuifInf_Bottom = 3000\n",
    "zbot[0,] = mtop - 30\n",
    "zbot[1,] = AcuifInf_Bottom + (0.85 * (mtop - AcuifInf_Bottom))\n",
    "zbot[2,] = AcuifInf_Bottom + (0.70 * (mtop - AcuifInf_Bottom))\n",
    "zbot[3,] = AcuifInf_Bottom + (0.50 * (mtop - AcuifInf_Bottom))\n",
    "zbot[4,] = AcuifInf_Bottom\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "372614a8",
   "metadata": {},
   "source": [
    "# Creación del modelo Modflow 6"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "14a50903",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create simulation\n",
    "model_name = 'regional_model'\n",
    "model_ws = '../examples/out/angascancha/model'\n",
    "exe_name = '../exe/mf6.exe'\n",
    "\n",
    "sim = flopy.mf6.MFSimulation(sim_name=model_name, version='mf6', exe_name=exe_name,sim_ws=model_ws)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "673e46d9",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create tdis package\n",
    "tdis_rc = [(1.0, 1, 1.0)]\n",
    "nper=len(tdis_rc)\n",
    "tdis = flopy.mf6.ModflowTdis(sim, nper=nper, time_units='seconds',perioddata=tdis_rc)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "029e5e52",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create iterative model solution and register the gwf model with it\n",
    "ims = flopy.mf6.ModflowIms(sim, linear_acceleration='BICGSTAB')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "e81013ed",
   "metadata": {},
   "outputs": [],
   "source": [
    "# create gwf model\n",
    "gwf = flopy.mf6.ModflowGwf(sim, modelname=model_name, save_flows=True, newtonoptions=['under_relaxation'])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "59fd85d6",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING: Unable to resolve dimension of ('gwf6', 'disv', 'cell2d', 'cell2d', 'icvert') based on shape \"ncvert\".\n"
     ]
    }
   ],
   "source": [
    "# disv\n",
    "disv = flopy.mf6.ModflowGwfdisv(gwf, nlay=nlay, ncpl=ncpl,top=mtop, botm=zbot,nvert=nvert, vertices=vertices,cell2d=cell2d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "e2ba23df",
   "metadata": {},
   "outputs": [],
   "source": [
    "ic = flopy.mf6.ModflowGwfic(gwf, strt=np.stack([mtop for i in range(nlay)]))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "5d3e6549",
   "metadata": {},
   "outputs": [],
   "source": [
    "Kx =[4E-4,5E-6,1E-6,9E-7,5E-7]\n",
    "icelltype = [1,1,0,0,0]\n",
    "npf = flopy.mf6.ModflowGwfnpf(gwf,save_specific_discharge=True,icelltype=icelltype,k=Kx)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "2131850d",
   "metadata": {},
   "outputs": [],
   "source": [
    "rchr = 0.15/365/86400\n",
    "rch = flopy.mf6.ModflowGwfrcha(gwf, recharge=rchr)\n",
    "evtr = 1.2/365/86400\n",
    "evt = flopy.mf6.ModflowGwfevta(gwf,ievt=1,surface=mtop,rate=evtr,depth=1.0)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "7e09f2c7",
   "metadata": {},
   "source": [
    "## Para insertar la red de drenaje se realiza una interceptacion entre el shp de rios y la grilla, de esta manera se optiene los indices de las celdas que conforman la red de drenaje"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "5cfe8558",
   "metadata": {},
   "outputs": [],
   "source": [
    "tgr = fgrid.VertexGrid(vertices, cell2d)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "id": "5c313a36",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.collections.LineCollection at 0x1e8e866a340>"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 234636 characters]\n",
      "text/plain": [
       "<Figure size 1080x720 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "tgr = fgrid.VertexGrid(vertices, cell2d)\n",
    "fig, ax = plt.subplots(1, 1, figsize=(15, 10))\n",
    "pmv = fplot.PlotMapView(modelgrid=tgr)\n",
    "pmv.plot_grid(ax=ax)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "id": "ffeba8af",
   "metadata": {},
   "outputs": [],
   "source": [
    "ix2 = GridIntersect(tgr)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "id": "d2c64be9",
   "metadata": {},
   "outputs": [],
   "source": [
    "rios=gpd.read_file('../examples/in/shp/rios.shp')\n",
    "list_rivers=[]\n",
    "for i in range(rios.shape[0]):\n",
    "    \n",
    "    list_rivers.append(rios['geometry'].loc[i])\n",
    "    \n",
    "mls = MultiLineString(lines=list_rivers)\n",
    "#intersec rivers with our grid\n",
    "result=ix2.intersect(mls)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "id": "302c6fe0",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 225984 characters]\n",
      "text/plain": [
       "<Figure size 576x576 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig, ax = plt.subplots(1, 1, figsize=(8, 8))\n",
    "pmv = fplot.PlotMapView(ax=ax, modelgrid=tgr)\n",
    "pmv.plot_grid()\n",
    "ix2.plot_linestring(result, ax=ax, lw=3)\n",
    "\n",
    "for cellid in result.cellids:\n",
    "    (h2,) = ax.plot(\n",
    "        tgr.xcellcenters[cellid],\n",
    "        tgr.ycellcenters[cellid],\n",
    "        \"kx\",\n",
    "        label=\"centroids of intersected gridcells\",\n",
    "    )\n",
    "\n",
    "ax.legend([h2], [i.get_label() for i in [h2]], loc=\"best\");"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 19,
   "id": "51ab712f",
   "metadata": {},
   "outputs": [],
   "source": [
    "#stress_period_data : [cellid, elev, cond, aux, boundname]\n",
    "drain_list = []\n",
    "for i in result.cellids:\n",
    "    drain_list.append([0,i,mtop[i],0.001])\n",
    "drain_spd = {0:drain_list}"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "id": "cfd4760a",
   "metadata": {},
   "outputs": [],
   "source": [
    "drn = flopy.mf6.ModflowGwfdrn(gwf,stress_period_data=drain_spd)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "id": "10118f4b",
   "metadata": {},
   "outputs": [],
   "source": [
    "hname = '{}.hds'.format(model_name)\n",
    "cname = '{}.cbc'.format(model_name)\n",
    "oc = flopy.mf6.ModflowGwfoc(gwf, budget_filerecord=cname,\n",
    " head_filerecord=hname,\n",
    " saverecord=[('HEAD', 'ALL'), ('BUDGET',\n",
    "'ALL')])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "id": "20ccfbd2",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "writing simulation...\n",
      "  writing simulation name file...\n",
      "  writing simulation tdis package...\n",
      "  writing ims package ims_-1...\n",
      "  writing model regional_model...\n",
      "    writing model name file...\n",
      "    writing package disv...\n",
      "    writing package ic...\n",
      "    writing package npf...\n",
      "    writing package rcha_0...\n",
      "    writing package evta_0...\n",
      "    writing package drn_0...\n",
      "INFORMATION: maxbound in ('gwf6', 'drn', 'dimensions') changed to 3399 based on size of stress_period_data\n",
      "    writing package oc...\n",
      "FloPy is using the following executable to run the model: ../exe/mf6.exe\n",
      "                                   MODFLOW 6\n",
      "                U.S. GEOLOGICAL SURVEY MODULAR HYDROLOGIC MODEL\n",
      "                            VERSION 6.3.0 03/04/2022\n",
      "\n",
      "   MODFLOW 6 compiled Mar 02 2022 15:29:04 with Intel(R) Fortran Intel(R) 64\n",
      "   Compiler Classic for applications running on Intel(R) 64, Version 2021.5.0\n",
      "                             Build 20211109_000000\n",
      "\n",
      "This software has been approved for release by the U.S. Geological \n",
      "Survey (USGS). Although the software has been subjected to rigorous \n",
      "review, the USGS reserves the right to update the software as needed \n",
      "pursuant to further analysis and review. No warranty, expressed or \n",
      "implied, is made by the USGS or the U.S. Government as to the \n",
      "functionality of the software and related material nor shall the \n",
      "fact of release constitute any such warranty. Furthermore, the \n",
      "software is released on condition that neither the USGS nor the U.S. \n",
      "Government shall be held liable for any damages resulting from its \n",
      "authorized or unauthorized use. Also refer to the USGS Water \n",
      "Resources Software User Rights Notice for complete use, copyright, \n",
      "and distribution information.\n",
      "\n",
      " \n",
      " Run start date and time (yyyy/mm/dd hh:mm:ss): 2022/06/03 15:53:20\n",
      " \n",
      " Writing simulation list file: mfsim.lst\n",
      " Using Simulation name file: mfsim.nam\n",
      " \n",
      "    Solving:  Stress period:     1    Time step:     1\n",
      " \n",
      " Run end date and time (yyyy/mm/dd hh:mm:ss): 2022/06/03 15:53:27\n",
      " Elapsed run time:  6.855 Seconds\n",
      " \n",
      "\n",
      "ERROR REPORT:\n",
      "\n",
      "  1.  Simulation convergence failure occurred 1 time(s).\n",
      " Premature termination of simulation.\n",
      " Premature termination of simulation.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "(False, [])"
      ]
     },
     "execution_count": 22,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "sim.write_simulation()\n",
    "sim.run_simulation()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "91d13d56",
   "metadata": {},
   "source": [
    "# plots"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "id": "0bc250a2",
   "metadata": {},
   "outputs": [],
   "source": [
    "hds = bf.HeadFile(model_ws+'/'+model_name + '.hds')\n",
    "head = hds.get_data(totim=1.0)\n",
    "head[head==1e+30]=np.nan\n",
    "cpth = os.path.join(model_ws, model_name+'.cbc')\n",
    "cobj = flopy.utils.CellBudgetFile(cpth, precision=hds.precision)\n",
    "spd = cobj.get_data(text='DATA-SPDIS')[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "id": "c504179f",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x1e8f8cda580>"
      ]
     },
     "execution_count": 24,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 314440 characters]\n",
      "text/plain": [
       "<Figure size 864x864 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure(figsize=(12, 12))\n",
    "ax = fig.add_subplot(1, 1, 1, aspect='equal')\n",
    "mapview = flopy.plot.PlotMapView(model=gwf)\n",
    "#linecollection = mapview.plot_grid()\n",
    "\n",
    "levels = np.linspace(np.nanmin(head),np.nanmax(head),num=50)\n",
    "contour_set = mapview.contour_array(head,levels=levels)\n",
    "t = ax.set_title(\"Model Heads\")\n",
    "plt.colorbar(contour_set, shrink=0.75)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 25,
   "id": "6b485727",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<matplotlib.colorbar.Colorbar at 0x1e8fb5926d0>"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "[encoded data, 296160 characters]\n",
      "text/plain": [
       "<Figure size 720x1080 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "fig = plt.figure(figsize=(10, 15))\n",
    "ax = fig.add_subplot(1, 1, 1, aspect='equal')\n",
    "mapview = flopy.plot.PlotMapView(model=gwf)\n",
    "\n",
    "quadmesh = mapview.plot_array(head, alpha=0.5)\n",
    "levels = np.linspace(np.nanmin(head),np.nanmax(head),num=50)\n",
    "c = mapview.contour_array(head, linewidths=0.75,colors='white',levels=levels)\n",
    "plt.clabel(c, fmt='%3d')\n",
    "#quiver = flopy.plot.plotutil.c(spd)\n",
    "plt.colorbar(quadmesh, shrink=0.75)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "id": "96da4a50",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 341280 characters]\n",
      "text/plain": [
       "<Figure size 864x864 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "vertex_ml6=sim.get_model(model_name)\n",
    "line = np.array([(624770.179,8348969.726), (620962.977,8356981.404), (632881.175,8372408.850)])\n",
    "\n",
    "# Let's plot the model grid in map view to look at it\n",
    "fig = plt.figure(figsize=(12, 12))\n",
    "ax = fig.add_subplot(1, 1, 1, aspect=\"equal\")\n",
    "ax.set_title(\"Vertex Model Grid (DISV) with cross sectional line\")\n",
    "\n",
    "# use PlotMapView to plot a DISV (vertex) model\n",
    "mapview = flopy.plot.PlotMapView(vertex_ml6, layer=0)\n",
    "linecollection = mapview.plot_grid()\n",
    "\n",
    "# plot the line over the model grid\n",
    "lc = plt.plot(line.T[0], line.T[1], \"r--\", lw=2)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "id": "10c9cf8a",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 23252 characters]\n",
      "text/plain": [
       "<Figure size 1296x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# get the head output for stress period 1 from the modflow6 head file\n",
    "head = flopy.utils.HeadFile(os.path.join(model_ws, model_name+\".hds\"))\n",
    "hdata = head.get_alldata()[0, :, :, :]\n",
    "\n",
    "fig = plt.figure(figsize=(18, 5))\n",
    "ax = fig.add_subplot(1, 1, 1)\n",
    "ax.set_title(\"plot_array()\")\n",
    "\n",
    "xsect = flopy.plot.PlotCrossSection(model=vertex_ml6, line={\"line\": line})\n",
    "patch_collection = xsect.plot_array(hdata, head=hdata, alpha=0.5)\n",
    "line_collection = xsect.plot_grid()\n",
    "cb = plt.colorbar(patch_collection, shrink=0.75)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 28,
   "id": "e2c09779",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 45144 characters]\n",
      "text/plain": [
       "<Figure size 1296x360 with 2 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "levels = np.arange(3600, 4300, 100)\n",
    "\n",
    "fig = plt.figure(figsize=(18, 5))\n",
    "ax = fig.add_subplot(1, 1, 1)\n",
    "ax.set_title(\"contour_array() with a multi-layer vertex model\")\n",
    "\n",
    "xsect = flopy.plot.PlotCrossSection(model=vertex_ml6, line={\"line\": line})\n",
    "patch_collection = xsect.plot_array(hdata, head=hdata, alpha=0.5)\n",
    "line_collection = xsect.plot_grid()\n",
    "\n",
    "contour_set = xsect.contour_array(hdata, levels=levels, colors=\"k\")\n",
    "plt.clabel(contour_set, fmt=\"%.1f\", colors=\"k\", fontsize=11)\n",
    "\n",
    "cb = plt.colorbar(patch_collection, shrink=0.75)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 29,
   "id": "ef01afe2",
   "metadata": {},
   "outputs": [],
   "source": [
    "hds = bf.HeadFile(model_ws+'/'+model_name + '.hds')\n",
    "head = hds.get_data(totim=1.0)\n",
    "head[head==1e+30]=np.nan\n",
    "cpth = os.path.join(model_ws, model_name+'.cbc')\n",
    "cobj = flopy.utils.CellBudgetFile(cpth, precision=hds.precision)\n",
    "spd = cobj.get_data(text='DATA-SPDIS')[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 30,
   "id": "e586e231",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 524532 characters]\n",
      "text/plain": [
       "<Figure size 1080x1080 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "head = gwf.output.head().get_data()\n",
    "bdobj = gwf.output.budget()\n",
    "fig = plt.figure(figsize=(15, 15))\n",
    "ax = plt.subplot(1, 1, 1)\n",
    "pmv = flopy.plot.PlotMapView(gwf)\n",
    "pmv.plot_array(head, cmap=\"jet\", alpha=0.5)\n",
    "pmv.plot_vector(spd[\"qx\"], spd[\"qy\"], alpha=0.25);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "4e442e93",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "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.13"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
