From 542aaca2d3f881252df9bb26c78e96ed03df277a Mon Sep 17 00:00:00 2001 From: adambeall1 Date: Tue, 18 Jul 2017 13:46:09 +1000 Subject: [PATCH] Adding darcy flow solver and groundwater example --- docs/examples/1_13_Groundwater_Flow.ipynb | 626 +++++--------- .../1_16_Groundwater_Heat_Advection.ipynb | 785 ++++++++++++++++++ underworld/systems/__init__.py | 1 + underworld/systems/_darcyflow.py | 262 ++++++ underworld/systems/_energy_solver.py | 5 +- underworld/systems/_solver.py | 2 + 6 files changed, 1247 insertions(+), 434 deletions(-) create mode 100644 docs/examples/1_16_Groundwater_Heat_Advection.ipynb create mode 100644 underworld/systems/_darcyflow.py diff --git a/docs/examples/1_13_Groundwater_Flow.ipynb b/docs/examples/1_13_Groundwater_Flow.ipynb index ffaac3ef1..e1bcf9a4c 100644 --- a/docs/examples/1_13_Groundwater_Flow.ipynb +++ b/docs/examples/1_13_Groundwater_Flow.ipynb @@ -1,5 +1,12 @@ { "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# 1D Darcy Flow (Groundwater) Solution and Benchmark" + ] + }, { "cell_type": "code", "execution_count": 1, @@ -12,59 +19,23 @@ "import glucifer\n", "import numpy\n", "import matplotlib.pyplot as plt\n", - "import mpi4py\n", - "\n", - "uw.matplotlib_inline()\n", - "plt.ion()\n", "\n", - "comm = mpi4py.MPI.COMM_WORLD\n", - "rank = comm.Get_rank()\n", - "size = comm.Get_size()\n", - "\n", - "# Whether or not to save figures to files in the current directory.\n", - "# Mainly useful when not using a notebook or for comparisons.\n", - "savefigures = False" + "uw.matplotlib_inline()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "### Groundwater Flow\n", - "\n", - "Underworld can efficiently solve the diffusion-advection equation and can set up as many simultaneous instances of it in a model as we would like. Heat-flow and groundwater flow are both described by this equation, so we can set these up and couple them, to model temperature advection by groundwater.\n", - "\n", - "**Temperature Diffusion-Advection Equation**\n", - "\n", - "$\\frac{\\partial T} {\\partial t} = \\kappa \\nabla^2 T + G$\n", - "\n", - "\n", - "where: $\\kappa = \\frac{k}{C_p \\rho}$\n", - "\n", - "($\\kappa$ - thermal diffusivity, $T$ - temperature, $t$ - time, $G$ - groundwater advection term, $C_p$ - heat capacity, $\\rho$ - rock density)\n", - "\n", - "**Groundwater Pressure Diffusion Equation**\n", - "\n", - "$\\frac{\\partial H} {\\partial t} = \\kappa_H \\nabla^2 H + F$\n", - "\n", - "where: $\\kappa_H = \\frac{k_H}{\\mu S}$\n", + "This notebook demonstrates the use of the ``uw.systems.SteadyStateDarcyFlow`` class, which solves for darcy flow (e.g. groundwater flow):\n", "\n", - "$F = \\frac{g}{S} \\frac{\\partial \\rho_w}{\\partial y}\\ \\ \\ $assuming constant $\\rho_w$, $\\ F=0$\n", + "$\\nabla q = 0$\n", "\n", - "($\\kappa_H$ - hydraulic diffusivity, $H$ - groundwater pressure, $k_H$ - hydraulic permeability, $\\mu$ - water viscosity, $S$ - specific storage, $g$ - gravitational accelleration, $\\rho_w$ - density of water)\n", + "$q = \\kappa \\left( -\\nabla p + S \\right)$ \n", "\n", - "**Groundwater Flow Equation**\n", + "where $q$ is the flow velocity, $p$ is the fluid pressure head, $\\kappa$ hydraulic diffusivity and $S$ is a hydraulic gradient source. $S$ is usually a gravitational term, for example $S = \\rho g$, where $\\rho$ is fluid density and $g$ is the gravitational accelleration vector.\n", "\n", - "$ q = \\frac{k_H}{\\mu}\\left(\\nabla H + \\rho_w g\\right) $\n", - "\n", - "\n", - "**Coupling**\n", - "\n", - "$G = -\\nabla T \\cdot \\frac{\\rho_w C_w}{\\rho C} q$\n", - "\n", - "($C_w$ - heat capacity of water)\n", - "\n", - "Coupling is implemented by handing an 'effective velocity field', $\\frac{\\rho_w C_w}{\\rho C} q$ to the temperature diffusion-advection solver.\n" + "We will set up a simple example of flow through two of strongly contrasting $\\kappa$ and compare the soultion to a 1D benchmark." ] }, { @@ -73,7 +44,9 @@ "source": [ "---\n", "\n", - "*Set up mesh and fields*" + "*Set up mesh and fields*\n", + "\n", + "**Note:** The velocity solution is extremely sensitive to the pressure gradient. A higher order shape function (Q2) may result in a more accurate solution of the pressure field, in the case of material variation within a cell, but the velocity would then be linearly variable within that cell. It is therefore best to use a linear shape function (Q1) and asign just one material per cell." ] }, { @@ -85,33 +58,27 @@ "outputs": [], "source": [ "\n", - "elementType = \"Q1/dQ0\"\n", + "elementType = \"Q1\"\n", "resX = 16\n", - "resY = 32\n", + "resY = 16\n", "mesh = uw.mesh.FeMesh_Cartesian( elementType = (elementType), \n", " elementRes = (resX, resY), \n", " minCoord = (-1., -1.), \n", - " maxCoord = (1., 0.)) \n", - "\n", - "temperatureField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", - "temperatureDotField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + " maxCoord = (0., 0.)) \n", "\n", "gwPressureField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", "hydraulicDiffusivityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", - "gwPressureDotField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", - "\n", - "velocityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=2 )\n", - "zerovelocityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=2 )\n", - "\n", - "domainVolume = (mesh.maxCoord[1] - mesh.minCoord[1]) * (mesh.maxCoord[0] - mesh.minCoord[0])\n", - "averageTemperature = uw.utils.Integral(fn = temperatureField / domainVolume,mesh= mesh,integrationType=\"volume\")" + "velocityField = uw.mesh.MeshVariable(mesh=mesh,nodeDofCount=2)\n", + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Set up the types of boundary conditions*" + "*Set up the types of boundary conditions*\n", + "\n", + "**Note:** The darcy-flow solver does also work for a lower free-slip boundary condition, but only if a strong horizontal flow component exists, such as arises when there is topographic variation. " ] }, { @@ -124,323 +91,152 @@ "source": [ "iWalls = mesh.specialSets[\"MinI_VertexSet\"] + mesh.specialSets[\"MaxI_VertexSet\"]\n", "jWalls = mesh.specialSets[\"MinJ_VertexSet\"] + mesh.specialSets[\"MaxJ_VertexSet\"]\n", - "insideNodes = []\n", - "for i in range(mesh.nodesLocal):\n", - " if i not in iWalls and i not in jWalls:\n", - " insideNodes.append(i)\n", - "\n", - "\n", - "\n", - "temperatureBC = uw.conditions.DirichletCondition( variable = temperatureField, \n", - " indexSetsPerDof = ( jWalls) )\n", + "topWall = mesh.specialSets[\"MaxJ_VertexSet\"]\n", + "bottomWall = mesh.specialSets[\"MinJ_VertexSet\"]\n", "\n", "gwPressureBC = uw.conditions.DirichletCondition( variable = gwPressureField, \n", - " indexSetsPerDof = ( jWalls) )\n", - "\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Set initial conditions and the values of the boundary conditions*" + " indexSetsPerDof = ( topWall+ bottomWall ) )\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "**This lower ground-water pressure is something that you can change. You can lower it until gravity dominates.**" + "*Choose the pressure set at the lower wall and set an initially linear pressure field which is consistent with the BCs*" ] }, { "cell_type": "code", "execution_count": 4, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [ - "#Lower groundwater pressure boundary condition\n", - "# this value is relative to gravity\n", - "maxgwpressure = 2." - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "Set up initial conditions. This includes whether or not you want to read in an existing temperature field. We will by default, because we will only run a couple of time steps." - ] - }, - { - "cell_type": "code", - "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "readTemperature = True\n", + "#Groundwater pressure boundary condition on the bottom wall\n", + "# this value is relative to gravity\n", + "maxgwpressure = 0.5\n", "\n", "yCoordFn = uw.function.input()[1]\n", + "initialFn = -1. * yCoordFn * maxgwpressure\n", "\n", - "if readTemperature:\n", - " temperatureField.load(\"input/1_13_Groundwater_Flow/temperature.h5\", interpolate=True)\n", - "else:\n", - " initialFn = -1. * yCoordFn\n", - " temperatureField.data[:] = initialFn.evaluate(mesh)\n", - "\n", - "initialFn = -1. * maxgwpressure * yCoordFn\n", - "gwPressureField.data[:] = initialFn.evaluate(mesh)\n", - "\n" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial Temperature Field\" )\n", - "figMaterial.append( glucifer.objects.Surface(mesh,temperatureField ))\n", - "if size == 1:\n", - " figMaterial.show()\n" + "gwPressureField.data[:] = initialFn.evaluate(mesh)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Set up swarm*" + "*Set up swarm*\n", + "\n", + "**Imporant Note:** The swarm is used for setting the $\\kappa$ for a cell. As a result of our choice of a linear shape-function (Q1), there is a single constant pressure gradient solved for each cell. If we were to use particles with strongly contrasting $\\kappa$ in one cell, the actual solution should involve a strong variation in pressure gradient which cannot be reproduced by the constant pressure gradient solved. It is therefore recommended that only one particle is used per cell. For the same reason, velocity should be calculated inside the cell, rather than on the mesh. Our swarm is used both for setting $\\kappa$ and calculating the velocity.\n" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 5, "metadata": { - "collapsed": true + "collapsed": false }, "outputs": [], "source": [ "swarm = uw.swarm.Swarm( mesh=mesh )\n", - "swarmLayout = uw.swarm.layouts.GlobalSpaceFillerLayout( swarm=swarm, particlesPerCell=10 )\n", - "swarm.populate_using_layout( layout=swarmLayout )" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Assign materials to particles*" + "swarmLayout = uw.swarm.layouts.PerCellGaussLayout(swarm=swarm,gaussPointCount=1)\n", + "swarm.populate_using_layout(swarmLayout)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "** Here we are deciding on the distribution of different materials. The benchmark is for a large region which extends from the bottom to the top of the domain, in this case on the left hand half of the model. Once you are happy with the benchmark, feel free to change the model geometries!** " + "Set up swarm variables: material ID and velocity. The velocity variable is where the velocity solution can be stored." ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [], "source": [ "materialIndex = swarm.add_variable( dataType=\"int\", count=1 )\n", + "materialVelocity = swarm.add_variable( dataType=\"double\", count=2 )\n", "\n", "materialPorous = 0\n", - "materialImpermeable = 1\n", - "\n", - "xCoordFn = uw.function.input()[0]\n", - "yCoordFn = uw.function.input()[1]\n", - "\n", - "conditions = [ (yCoordFn > 0., materialPorous),\n", - " ( xCoordFn < 0. , materialPorous),\n", - " ( True , materialImpermeable )]\n", - "\n", - "\n", - "materialIndex.data[:] = uw.function.branching.conditional( conditions ).evaluate(swarm)\n", - "\n", - "\n", - "\n" + "materialImpermeable = 1\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Visualise the materials we have just assigned*" + "Set up a horizontal interface between the two materials" ] }, { "cell_type": "code", - "execution_count": 9, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/html": [ - "" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial Material Distribution\" )\n", - "figMaterial.append( glucifer.objects.Points(swarm, materialIndex, pointSize=4.0) )\n", - "if size == 1:\n", - " figMaterial.show()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Assign material properties*" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "**Here we have material properties which are chosen relative to the thermal diffusion time-scale. Leave the thermal diffusivity as 1, but you can change the maximum hydraulic diffusivity to control their relative time-scale (along with the chosen pressure gradient above). Feel free to change it!**\n", - "\n", - "**The storage capacity effectively controls the ratio of groundwater pressure diffusion to groundwater flow. The ratio of $\\rho_w c_w / \\left( \\rho c \\right)$ controls the rate of energy transfer from the water to the rock matrix. $\\rho_w$ also affects the gravity term in the ground-water flow equation ... denser water will sink in the absence of an upward pressure decrease.**" - ] - }, - { - "cell_type": "code", - "execution_count": 10, + "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "maxHydDiff = 1.\n", - "hydraulicDiffusivityMap = { materialPorous : maxHydDiff, \n", - " materialImpermeable : 1e-5}\n", - "hydraulicDiffusivityMapFn = uw.function.branching.map( fn_key = materialIndex, mapping = hydraulicDiffusivityMap )\n", - "\n", - "#Hydraulic storage capacity\n", - "Storage = 1.\n", - "\n", - "rho_water = 1.\n", - "rho_rock = 2.5\n", - "\n", - "c_w = 4000.\n", - "c = 1250.\n", + "xCoordFn = uw.function.input()[0]\n", + "yCoordFn = uw.function.input()[1]\n", "\n", - "# g = 1.\n", - "g = uw.function.misc.constant((0.,1.))\n", + "interfaceY = -0.25\n", "\n", + "conditions = [ (yCoordFn > interfaceY, materialPorous),\n", + " ( True , materialImpermeable )]\n", "\n", - "thermalDiff = 1.\n", - "thermalDiffusivityMap = { materialPorous : thermalDiff, \n", - " materialImpermeable : thermalDiff}\n", - "thermalDiffusivityMapFn = uw.function.branching.map( fn_key = materialIndex, mapping = thermalDiffusivityMap )" + "materialfn = uw.function.branching.conditional( conditions )\n", + "materialIndex.data[:] = materialfn.evaluate(swarm)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Setup groundwater equations*" + "Assign a different $\\kappa$ to each material. The upper layer in this case is much more permeable than the lower." ] }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [], "source": [ + "Ka = 1.\n", + "Kb = 1e-3\n", "\n", - "gwadvDiff = uw.systems.SteadyStateHeat( temperatureField = gwPressureField, fn_diffusivity = hydraulicDiffusivityMapFn,conditions=[gwPressureBC])\n", - "\n", - "gwsolver = uw.systems.Solver(gwadvDiff)\n", - "\n", - "hydraulicProjector = uw.utils.MeshVariable_Projection(hydraulicDiffusivityField,hydraulicDiffusivityMapFn)\n", - "hydraulicProjector.solve()\n" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "*Gradients - needed for calculating ground-water flow and advection*" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "tempGrad = temperatureField.fn_gradient\n", - "gwPressureGrad = gwPressureField.fn_gradient\n" + "hydraulicDiffusivityMap = { materialPorous : Ka, \n", + " materialImpermeable : Kb}\n", + "hydraulicDiffusivityMapFn = uw.function.branching.map( fn_key = materialIndex, mapping = hydraulicDiffusivityMap )\n", + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Ground-water Velocity*" + "Let's check that the $\\kappa$ asigned to each particle looks correct:" ] }, { "cell_type": "code", - "execution_count": 13, - "metadata": { - "collapsed": false - }, - "outputs": [], - "source": [ - "gwVelField = -1.*rho_water / rho_rock * c_w / c *(g *rho_water + gwPressureGrad)* hydraulicDiffusivityField * Storage\n", - "velocityfieldProjector = uw.utils.MeshVariable_Projection(velocityField,gwVelField)\n", - "\n", - "velocityfieldProjector.solve()\n" - ] - }, - { - "cell_type": "code", - "execution_count": 14, + "execution_count": 9, "metadata": { - "collapsed": false + "collapsed": false, + "scrolled": false }, "outputs": [ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -451,102 +247,80 @@ } ], "source": [ - "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial ground-water pressure and velocity vectors\" )\n", - "figMaterial.append( glucifer.objects.Surface(mesh,gwPressureField ))\n", - "figMaterial.append(glucifer.objects.VectorArrows(mesh,gwVelField,scaling=0.03))\n", - "if size == 1: \n", - " figMaterial.show()\n" + "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Hydraulic Diffusivity\" )\n", + "figMaterial.append( glucifer.objects.Points(swarm, hydraulicDiffusivityMapFn, pointSize=5.0) )\n", + "\n", + "figMaterial.append( glucifer.objects.Mesh(mesh))\n", + "figMaterial.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Setup temperature advection-diffusion solver*" + "*Setup the dary flow (groundwater) equation*" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "tempadvDiff = uw.systems.AdvectionDiffusion( temperatureField, temperatureDotField, \n", - " velocityField, \n", - " fn_diffusivity=thermalDiffusivityMapFn, conditions=[temperatureBC,] ) \n" + "g = uw.function.misc.constant((0.,-1.))\n", + "\n", + "\n", + "gwadvDiff = uw.systems.SteadyStateDarcyFlow(velocityField=velocityField,\n", + " pressureField = gwPressureField, fn_diffusivity = hydraulicDiffusivityMapFn,\n", + " conditions=[gwPressureBC],fn_bodyforce=g, \n", + " voronoi_swarm=swarm,swarmVarVelocity=materialVelocity)\n", + "gwsolver = uw.systems.Solver(gwadvDiff)\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "For a ground-water velocity $q$, this the following is an analytic solution to the 1D temperature diffusion-advection equation: $\\frac{d^2 T}{dy^2} + q'\\frac{dT}{dy} = 0$\n", - "\n", - "where: $q' = \\frac{\\rho_w c_w}{\\rho c} \\frac{q}{\\kappa}$\n", - "\n", - "The solution, assuming $H=0$ and $T=0$ at the surface and $H = H_{max}$ and $T=1$ at the base of the domain, is:\n", - "\n", - "$T(y) = \\alpha \\left(e^{q' y} - 1 \\right)\\ \\ \\ $ where: $\\alpha = \\left( e^{-q'}-1 \\right)^{-1}$ (you can check it's actually a solution)\n", - "\n", - "\n", - "We can use this to benchmark an effectively 1D part of the domain." + "*Solve*" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [], "source": [ - "def analyticsol(y):\n", - " qp = rho_water / rho_rock * c_w / c * maxHydDiff / thermalDiff * Storage * (maxgwpressure - rho_water)\n", - " \n", - " if qp == 0.:\n", - " return -y\n", - " else:\n", - " return (numpy.exp(qp*y) - 1.) / (numpy.exp(-qp) -1. )" + "gwsolver.solve()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "We solve for the groundwater pressure diffusion first, as it temperature-independent. Because the temperature advection-diffusion depends on groundwater flow, but not the other way round, we can solve for groundwater pressure first. There is no source term, so we can use the steady-state solver." - ] - }, - { - "cell_type": "code", - "execution_count": 17, - "metadata": { - "collapsed": false, - "scrolled": true - }, - "outputs": [], - "source": [ + "*Visualise the groundwater solution, by plotting it for $x=-1$ (left wall).*\n", "\n", - "gwsolver.solve()\n", + "This model is simple enough that there is an equivalent 1D analytic, which we can use as a benchmark. Out of interest, let's also plot what the solution would look like without the gravity term.\n", "\n", - "velocityfieldProjector.solve()\n" + "The grey lines are the horizontal element edges. Note that an resolution has been chosen so that the interface boundary is accurately resolved." ] }, { "cell_type": "code", - "execution_count": 18, + "execution_count": 12, "metadata": { - "collapsed": false + "collapsed": false, + "scrolled": true }, "outputs": [ { "data": { - "text/html": [ - "" - ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEPCAYAAABsj5JaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmcjWX/wPHPd8xQ9hkZS8aSJS0iRfoRI1FJJEXWSKVF\npFKR9cmTyPNoI4WyL9FTlh5lHZEWIoYIKXsqnsEYZpj5/v44xzTMjNnOOfc5Z77v1+u8nHPf17nv\n79xmzvdc13Vf1yWqijHGGJNTIU4HYIwxJjBZAjHGGJMrlkCMMcbkiiUQY4wxuWIJxBhjTK5YAjHG\nGJMrjicQEblLRHaIyE4ReSmTMm+LyC4R+VFE6vg6RmOMMek5mkBEJAR4F7gTuA7oKCI1LypzN1BV\nVasDvYAJPg/UGGNMOk7XQOoDu1R1r6qeBeYAbS4q0waYBqCq3wElRKSMb8M0xhhzMacTyJXA/jSv\nD7i3XarMwQzKGGOM8TGnE4gxxpgAFerw+Q8CFdO8ruDednGZqCzKACAiNrGXMcbkkKpKbt7ndA1k\nPVBNRCqJSEHgIWDhRWUWAt0ARKQBEKeqRzI7oKqiqgwdOpTFQ4dSoUABfu7SBY2PT92Xnx5Dhw51\nPAZ/eNh1sGth1yHjR144mkBUNRnoDSwFtgFzVHW7iPQSkcfdZf4L/Coiu4H3gaeye/x7hg1j5759\n1ACoUwfWrvX4z2CMMfmV001YqOoXwNUXbXv/ote9c3v8y8uXh+nT4bPPoH176NgRRoyAyy/P7SGN\nMcbgfBOWV0yfPp2IiIgLN953H2zZAgcOwI03cmjxYmeC87Ho6GinQ/ALdh3+ZtfCxa5D3kle28D8\niYioqrJ69WoiIyO55pprMix3cto0runRg6716zPsyy8pVLy4jyM1xhj/ICJoLjvRgzKBZMeRrVt5\nskULdh47xpSJE7m5a1cvR2dM4KlcuTJ79+51OgzjAZUqVeK3335Lt90SiFtOEgiApqQw+5lnePa9\n9+jVsCGDlyyhYNGiXozQmMDi/nBxOgzjAZn9X+YlgQRlH0h2SUgIncaNY/PGjfz6668cu+UW2LzZ\n6bCMMSYg5OsayAVUYdo06N8fnnkGXn4ZwsI8G6AxAcZqIMHDaiDZNGPGDL766qucvUkEHn4YNm50\njRe59VbYts07ARpjTBAIygSyZs0atm/fnrs3V6gAX3wBjz9OcpMmTGvfnuTERM8GaIwJemvXrs30\nTtCcqFKlCitXrvRARJ4XlAkkz0Tg8cc5sWIFU5Yto9EVV/DzkiVOR2WMuUjlypUpU6YMp0+fTt02\nefJkmjZt6mBULo0aNcr9F9kAEZQJpHPnztx22215Pk547dos//NPutx9Nw3vuYexbdqQnJTkgQiN\nMZ4gIqSkpPDmm2+m2+6k5ORkR8/vK45PZeINjRs3ZtGiRfzyyy8eOV7Frl157YYbeOu115hYsiSv\njBhB8erVPXJsY0ze9O/fn9GjR/P0009TPM2g4L1791KlShXOnTtHSIjru3LTpk3p2rUrjzzyCFOn\nTmXixInUr1+fjz76iFKlSjF9+nR27tzJ4MGDSUpKYvTo0XTr1g2ApKQkBg4cyLx580hKSqJt27aM\nHTuWQoUKsXr1arp06cIzzzzD2LFjadGiBY888ghdunRh/37XckYHDhygb9++rFmzBlWlY8eOvP32\n2+zZs4fHHnuMzZs3ExISQosWLRg/fvwFP4unLFq0yLMHdHomSA/PKqnelHz2rM7s0kXPRUSovvOO\nanKyV89njNO8/TeVV5UrV9YVK1Zou3btdNCgQaqqOmnSJG3atKn+9ttvGhISoslp/k6jo6N18uTJ\nqqo6ZcoUDQsL06lTp2pKSooOGjRIK1asqL1799akpCRdunSpFitWTE+dOqWqqs8++6y2adNG4+Li\nND4+Xlu3bq0DBw5UVdWYmBgNDQ3VAQMGaFJSkp45c0ZjYmI0KipKVVWTk5O1du3a+vzzz+vp06c1\nMTFRv/76a1VV3b17ty5fvlzPnj2rf/31lzZp0kT79euX7mfMq8z+L93bc/eZm9s3+uPDZ7/sO3ao\nNmig2rSp6q+/+uacxjggW39Trpvg8/7IhfMfrlu3btWSJUvqX3/9laMEUqNGjdR9sbGxGhISon/+\n+WfqtlKlSunmzZtVVbVIkSK6Z8+e1H3r1q3TKlWqqKorgRQqVEiTkpJS96dNIOvWrdPIyMgLYsnM\nZ599pnXr1k33M+aVNxJIUDZhed3VV7tu9f3Xv6BePdfsvo8/7up8Nya/UefHiVx33XW0atWKkSNH\n5ujOpzJlyqQ+v9w9Q/cVV1xxwbb4+Hj+/PNPEhISuOmmm1L3paSknP/iCkDp0qUJy2Ts2IEDB6hU\nqVJqU1paf/zxR2rTVnx8PMnJyekng/VTQdmJPnPmTGJiYrx7kgIF4MUXYfVqjrz3Hh3KlWP/d995\n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\nzp2qqtqoUSOdOnWqqqpOnjxZq1evrr/99pueOnVK77//fu3atWuGx1+yZImWK1dOt2/frqdPn9Yu\nXbpoSEiI/vLLL6qq2r17dy1ZsqR+8803qqqamJioq1ev1q1bt6qqamxsrJYtW1YXLFigqqrTpk3T\nhg0bph5/27ZtGh4ermfPnlVVTXfswYMHp5Y9fPiwFi1aVI8fP66qqufOndPIyEjdtGlTapl///vf\n2q5duwx/lsz+L93bc/WZG5STKYLnZ500FyresiW7pk7ltSefpFbLlk6HY/KpuLg4ihUrlm57ZGQk\nTzzxROrsuWnNmjWL5557jkqVKgEwcuRIrr/+eqZMmZJuwsN58+bRo0cPatasCbjuHEs7XTxAmzZt\naNCgAeC607Nx48ap+66//noeeughVq9eTevWrWnbti1PPfUU+/fvJyoqilmzZnH//fcTGur6KNZL\nNAuXLVuWxo0bM2/ePHr27MmSJUsoXbo0derUSS1TrFgx4uLiMj2GzcabTXmZdfLw4cOUKVMmwymY\nzd/iOndm2rx5DHzvPadDMflUeHh4ps1PL730EtWqVUs3M++hQ4dSkwdApUqVOHfuHEeOHEmd1Tdt\n2Xr16qW+joqKSvchf/EcWt9//z0vv/wyW7duJSkpiaSkpNSFpooWLUrLli2ZM2cO/fv3Z/bs2Uya\nNCnbP2+3bt2YMGECPXv2ZObMmekmdjx58iQlS5bM9P02G68P9O3bl2+//dbpMPxe5/HjuTExkUT3\n7KLG+NoNN9zAzp07M9wXERHBs88+y+DBgy8Y/1W+fHn27t2b+nrv3r2EhYVRpkyZdMcoV64cBw4c\nSH29b9++dGPJLn7dqVMn7rvvPg4ePEhcXBy9evW6IOl07NiRWbNm8e2335KYmEjTpk0zjD+jMWv3\n3XcfW7ZsYdu2bSxevJjOnTtfsH/79u3Url07w+N5gyWQDMyePTt11TCTubCiRfnXyJEUGjXK6VBM\nPtWyZUtiLjEmqV+/fqxbt47t27enbuvYsSNjx47lt99+Iz4+nldeeYWHHnoowxaH9u3b89FHH7Fj\nxw4SEhIYMWJEljHFx8cTHh5OWFgY33//fbomr5YtW7J3716GDBlChw4dMj1OmTJl0k0TX6hQIdq1\na0enTp245ZZbqFChwgX7V69ezd13351ljJ5iCSQDaZeqNFl49FHYsAE2bXI6EpMPdevWjSVLlpCY\n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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -554,26 +328,59 @@ } ], "source": [ - "figMaterial = glucifer.Figure( figsize=(800,400),title=\"Ground-Water Pressure Field and Velocity Vectors\" )\n", - "figMaterial.append(glucifer.objects.Surface(mesh,gwPressureField,))\n", - "scale = 0.03\n", - "figMaterial.append(glucifer.objects.VectorArrows(mesh,velocityField*scale,scaling=1.))\n", - "if size == 1:\n", - " figMaterial.show()\n" + "\n", + "if uw.rank() == 0:\n", + " arrX = numpy.linspace(-1,0,2)\n", + " plt.ylim(-1,0.)\n", + " plt.xlim(-1e-2,1)\n", + "\n", + "arrY = numpy.linspace(-1,0.,100)\n", + "x = -1.\n", + "arrP = gwPressureField.evaluate_global(numpy.array(zip(numpy.ones(100)*x,arrY)))\n", + "\n", + "if uw.rank() == 0:\n", + " plt.plot(arrP,arrY,c='red',label='Numerical')\n", + "\n", + "\n", + " for S in [1.,0.]:\n", + " La = -1. * interfaceY\n", + " Lb = 1. + interfaceY\n", + " dP = maxgwpressure\n", + " Pa = (dP/Lb - S + Ka/Kb * S) / (1./Lb + Ka/Kb/La)\n", + " arrYl = numpy.linspace(-La,0.,3)\n", + " if S == 0.:\n", + " label = \"Analytical\\n(No gravity)\"\n", + " line = \"-.\"\n", + " else:\n", + " label = 'Analytical'\n", + " line = \"--\"\n", + " plt.plot(Pa*(-arrYl)/(La),arrYl,line,c=\"black\",label = label)\n", + " arrYl = numpy.linspace(-La,-1,3)\n", + " plt.plot(Pa + (dP-Pa)*(-arrYl-La)/Lb,arrYl,line,c=\"black\")\n", + " \n", + "if uw.rank() == 0:\n", + " plt.xlabel('Pressure')\n", + " plt.ylabel('Depth')\n", + " plt.legend()\n", + " \n", + " for meshY in numpy.linspace(-1,0,resY+1):\n", + " plt.plot(numpy.linspace(0,1,2),numpy.ones(2)*meshY,c=\"black\",alpha=0.3)\n", + "\n", + " \n", + " plt.savefig('PressureSolution.pdf')\n", + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Now solve for the temperature.*\n", - "\n", - "**This could certainly take a while to reach a steady-state. Look at the figures below and make sure that the mean temperature does not vary by the end of the loop. If the left hand wall of the model is homogeneous and is therefore effectively 1D, with purely vertical ground-water flow, check that this solution agrees with the analytic solution**" + "The velocity solution was found on the swarm, so let's visualise the swarm variable where it is kept. The vertical component of the velocity vector field is visualised. Note the colourbar - the solution is relatively constant, as it should be for flow conservation." ] }, { "cell_type": "code", - "execution_count": 19, + "execution_count": 13, "metadata": { "collapsed": false, "scrolled": true @@ -581,9 +388,11 @@ "outputs": [ { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYgAAAEZCAYAAACNebLAAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xl4FFXW+PHvSUAgkEDYIYSwI+CKiKiIQV8VUARxAySg\njMqIuAz6G2RGBVxHRVFeHZURERdABUYZlGVG3qiMzoiKogjKGiCgImvYITm/P6rSdJrupLpJZeN8\nnqceuqpu3Tpdafp23XvrXlFVjDHGmFBxpR2AMcaYsskKCGOMMWFZAWGMMSYsKyCMMcaEZQWEMcaY\nsKyAMMYYE5YVEMZUACIyREQ+9SHfdSJyUXHna8oHKyCMr0RkoIgsEZEcEckWkQ9E5PzSjqs8EpHL\nRORjEdktIr+IyP+JyBVBSeyhJlOsrIAwvhGRkcAzwCNAfaAp8ALQuzTjCiYi8aUdgxcicg3wDvAa\nkKKqDYAHKUPX0lQ8VkAYX4hIEjAOGK6q76vqflXNVdUPVfU+N81JIvKse2exSUQmiEhld9+FIrJR\nREa6v5azReRGd19nEdkiIhJ0vqtE5Fv3tYjIfSKyWkS2isgMEanl7ksTkTwRGSoiWcBH7vbBIrLe\nTX9/cNWKx/wGi0iWiPwqIn8KiitORP7kHrvLvZtKcfedLCILRWSbiKwQkWsLuaRPA+NUdYqq5gCo\n6qeqOqzgZZenRGS7iKwRkR7Bfw8ReUVENrvX9eGQ63eLiPzg3p18LyJnhPmbthORtSJyfZEfAFMh\nxFRAiMjQ4g7EVDjnAlWA9wpJcz/QGTgNON19fX/Q/oZAItAYuBl4QURqquoXwB4guG58APCm+/pO\n4ErgAvfYHcBfQ87dDTgZuExE2uHc2QwAGgE13ePyecnvfKA18D/AgyLS1t1+D3A90ENVawJDgX0i\nkgAsdGOuC/R339/JoRfJzasJMCt0X4hzgBVAHeApYHLQvqnAIaAFcCZwCc41xS2YHgQGqWqS+163\nhcTQEZgP3K6qbxcRh6koVDXqBedXYUzH2nJiLMBAYHMRaVYDlwWtXwqsdV9fCOwF4oL2/wJ0dl8/\nDEx2XyfiFBhN3PUfgO5BxzXC+XKMA9KAXCAtaP8DwFtB69WAg8BFUeTXKGj/f4Hr3NcrgSvCvPfr\ngI9Dtr0EPBAm7XnuOU4q5FoOAX4KeQ95OFV79YEDQJWg/f2Bj9zX84E7IuS7DhgLbAQuKO3PlS0l\nu1TyWpAEU9XQX0/GhNoG1BWROFXNi5CmMbAhaD2Lgr/ct4Ucuw+o4b6eBvxbRH4P9AO+UtVN7r40\n4O8ikn+sAIeBBkF5bQp63RjnCxAAVd0vIsG/oL3k90uEOFOBtRwrDegiItuD8owH3giTNj+WRjjX\nKJKfQ94Dbhx1gMrAFnebuEv+tU8F1hSS7zCcwqzYe0mZsi1iASEidxZ2oKpOLP5wTAXyOc6v8L7A\n7AhpsnG+KFe462nAZi+Zq+oKtw2hF07V0LSg3RuAoar6eehxIpKWn0XQ5i1Am6A01XC+VKPJL5KN\nQEucu5DQ7ZmqelkRx6OqP4rIRuBqnEb/aG3EuYOoo6rhejrlxxjJ74FRIvKMqo6M4fymnCqsDaJe\nEYsxEanqbmAMTr16HxGpJiKVRKSniPzFTTYDuF9E6opIXZyqnnC/oCOZBtyF0zbwbtD2l4HHRKQp\ngIjUE5Erg/YLBc0EeotIF7eRfGzI/mjzC/YK8LCItHKPPVVEkoG5QBsRGeRel8oi0ilcG4TrHuAB\ncZ53SHQbzruKyEuFnBsAVf0Zp71jQtCxLUSkW1CM97rtDIhISxFJDcoiB+gBdBORx4s6n6lASruO\ny5aKveD8ul+C8yWzGfgH0MXdVwV41t2eDUzArWfHaYPYEJLXWtx2AXc9FTgCzAlJJ8DdOPX/u4BV\nwCPuvvw2g7iQYwbjVN9sBf6M86v6/FjyAxbh3HGA8yPsT27su3DaJxq7+1rjFBS/uuf9F3BaIdfy\nUuATYDdOldYioKe7bwjwSUj6XKCF+zoRp2F9I04j+1e47STu/lvd97cbWAacHnrNgWRgKU5vqlL/\nbNni/yLuHz4iEWkMPAd0dTd9AvxBVT1VBbhd7Z51/6NMVtUnwqRJx/lyqAxsVdXuXvI2xg8iUh3Y\nCbRS1cLq/I2p0Lx0c52Cc3vazF3+6W4rkojEAc8DlwEdgAGht9AiUhOni+EVqnoKUFhfcGN8ISJX\nuNVg1XGeOVhmhYM50XkpIBqo6t9U9aC7vELB3huF6QysUtUsVT2MU+fcJyTNQGCWqmYDqOpvXoM3\nphj1wanq2oTTYNu/dMMxpvR5KSC2i0h/Oep6YHuRRzlSCOo+iPOfLyUkTRugtjjjyiwRkQyPeRtT\nbFT1FlVNdpdLVHVVacdkTGnz8hzEUJzGrRfc9c/dbcUZQ0ecp2KrA5+LyOequroYz2GMMSZKRRYQ\nqroep695LLJxBmjL18TdFmwT8JuqHgAOiMgnOMMuFCggRMRGqjTGmBioamFdsSOKWMUkzmBm+X23\nRUQmuYOKfR1uIK8IlgCtxBnQ7CScet05IWneB7qKSLw7Pk3+eDLHKO0uXxVpGTNmTKnHUJEWu552\nLcvqcjwKu4MYydGHlq4Hzgba4wz0NRFnsLNCqWquiIzA6QWV3811hYgMc3brJFVdKSILcPpe5wKT\nVDX0qVNjjDElrLAC4og6PY/AGXN+qqr+AswXkce8nkBV5wNtQ7a9HLI+HhjvNU9jjDH+K6wXk4pI\nAxGpAlyM85Rnvmr+hmX8lp6eXtohVCh2PYuPXcuyI+KT1CLSh6Nj3i9U1Zvc7RcAo1U11obrmIiI\nHm99mjHGnGhEBI2xkbrQoTbchuWaqro1aFuie9zuWE4YKysgjDEmer4VEGWJFRDGGBO94ykgbE5q\nY4wxYVkBYYwxJqwiCwgRudIdcTV/vZaIXOFvWMYYY0qbl/kgvlHVM0K2LVXVM32N7Ng4rA3CGGOi\n5HcbRLiMvQzyZ4wxphzzUkAsFZEn3fGU0kTkKZxpB40xxlRgXgqIEW66990FYLhvERljjCkT7DkI\nY4ypwI6nDSJiW4KIPK2q94jI34FjvplVtV8sJzweO3eW9BmNMebEVVhj89vuv8+XRCBeNGtW2hEY\nY8yJI2IBoapfuC/bqWqBQsKd4+EjPwMLx+4gjDEmOhJT5ZLDSyN1uPmnfxf7KY0xxpQHhbVBXI8z\nRWhzEZkdtCsRsN/yxhhTwRXWBvEFsA1oArwQtD0Hew7CGGMqvMLaINYB60SkDfClqu4qubCMMcaU\nNi9tEE2Br0Vkmoj8j98BGWOMKRs8PSgnInFAT+Am4HRgOvCqqq73NbqCMdiDcsYYEyXfJwxS1Txg\nvbvkAY2A90Xk8VhOaowxpuzzMtz37cAQYDcwGZitqgfdu4rVqtrC/zDtDsIYY2Lhy1AbQRoDA1R1\nTfBGVc0TkStjOakxxpiyL+IdhIgkFXagqu72JaII7A7CGGOi59cdxHKODtIXmrni9G4yxhhTQdlw\n38YYU4H53QaBiNQEWgJV87ep6mexnNAYY0z5UGQ3VxH5HfAZsAh4wv33Ma8nEJEeIrJSRH4SkVFh\n9l8oIjtF5Gt3uT+K+I0xxvjEy3MQdwOdgPWqegFwFs4YTUVyu8I+D1wGdAAGiMjJYZJ+oqod3eUR\nb6EbY4zxk5cC4oCq7gcQkZNUdTnQ1mP+nYFVqpqlqoeBGUCfMOmOY8RyY4wxfvBSQGwRkVrAP4AF\nIjIL2OQx/xRgY9D6JndbqHNF5BsR+UBE2nvM2xhjjI+KbKRW1fyH4R4QkYuBmsAHxRjDV0BTVd0n\nIj2B94A2xZi/McaYGHjtxSRAPWCFu6kOsNnDodkUfF6iibstQFX3BL2eJyJ/FZHaqro9NLOxY8cG\nXqenp5Oenu4lfGOMOWFkZmaSmZlZLHl5GYtpOPAQTsN0nrtZVbXIqiARiQd+BC4GtuBMQjRAVVcE\npWmgqr+4rzsD76hqszB52XMQxhgTJb+fgxgJtFPVrdFmrqq5IjICWIjT3jFZVVeIyDBnt04CrhGR\n24DDwH7g+mjPY4wxpvh5uYPIBC5W1dwSiShyHHYHYYwxUfL7DmI1sEhE5gIH8zeq6sRYTmiMMaZ8\n8FJAbHGX4NFd7ae8McZUcFEP1iciJwGXq+rf/Qkp4nmtiskYY6Lk+5SjIhInIpeKyBRgA84Mc8YY\nYyqwQquYROR8YCBwBbAUOBdoGfzsgjHGmIqpsBnlsoBVwBRgjqrmiMg6VW1ekgEGxWNVTMYYEyW/\nqpj+AbTAGVzvUhGpijVOG2PMCaPQRmp3uO6LgQE4Q3Yn4bQ/zFfVfSUS4dFY7A7CGGOidDx3EJ57\nMbm9l3rhFBYXq2rdWE4YKysgjDEmeiVSQIScsLqq7o3lhLGyAsIYY6LnezfXUCVdOBhjjCl5MRUQ\nxhhjKj4rIIwxxoRV5FhMItIRGA2kuekFZ6jujj7HZowxphR5GaxvOk4B8R1HJwwyxhhTwXkpILap\n6mzfIzHGGFOmeJkw6DKgH/AvCs4HMcff0I6Jw7q5GmNMlPyeMOgG4FSgBkFzUgMlWkAYY4wpWV4K\niHNUta3vkRhjjClTvHRz/a+IWAFhjDEnGC93EGcCy0RkNU4bhHVzNcaYE4CXAqKv71EYY4wpc4qs\nYlLVNUBV4BJ3qepuM8YYU4EVWUCIyAjgXaCpu7wjIsP9DswYY0zp8vIcxDLgvPx5qEWkBvCZqp5W\nAvEFx2HPQRhjTJT8Hu5bgENB64fdbcYYYyowL43Ub+B0dZ3lrl8FTPUvJGOMMWWBpxnlRKQz0NVd\n/VRVl/gaVfgYrIrJGGOi5NuUoyISDyxT1Q6xBldcrIAwxpjo+dYGoaq5wFoRSYkpMkBEeojIShH5\nSURGFZLubBE5LCL9Yj2XMcaY4uOlDaIGsEJEPgcCc1GrapFf5CISBzwPXAxsBpaIyPuqujJMur8A\nC6KI3RhjjI8iFhAiUklVjwCPHEf+nYFVqprl5jkD6AOsDEl3BzATOPs4zmWMMaYYFXYH8QXQEchQ\n1RtjzD8F2Bi0vgmn0AgQkcZAX1Xt7jaGG2OMKQMKKyBOEpHrgAtE5MrQncU4YdCzQHDbRMTGlLFj\nxwZep6enk56eXkwhGGNMxZCZmUlmZmax5BWxF5OIXAgMwplN7sOQ3aqqg4vMXKQLMFZVe7jr97nH\nPhGUZm3+S6AuTjvHraEFkPViMsaY6PnWzdXNfJiqvhxjYPHAjziN1Ftwqq0GqOqKCOmnAP8INwe2\nFRDGGBM9X6ccjbVwcI/NdQf7W4jTpXayqq4QkWHObp0Uekis5zLGGFO8PD1JXRbYHYQxxkTP78H6\njDHGnIA8FRAi0l9E/uy+ThWRs/wNyxhjTGnzMmHQ80B3nB5N4PQyesnPoIwxxpQ+L0NtnKeqHUVk\nKYCqbheRk3yOyxhjTCnzUsV02B0rSQFEpA6Q52tUxhhjSp2XAuIFYBZQT0TGAYuBJwo/xBhjTHnn\ndcKgDsD/4Dzt/C9V/d7vwMLEYN1cjTEmSn4/SX02sEJV97jriUBbVf0ylhPGygoIY4yJnt/PQUwC\n9gWt7wVifrraGGNM+eClgIhT1UCjtPu6sn8hGWOMKQu8FBDrROQ2EYkXkTgRuR1Y73NcxhhjSpmX\nAmIYzmisv7jLhcAtfgZljDGm9NlgfcYYU4H5Oty3iNQFhgLNgtOr6q2xnNAYY0z54GWojfeB/+A8\nIJfrbzjGGGPKCi/PQXyjqmeUUDyFxWFVTMYYEyW/n4OYJyKXxpK5McaY8svLHcQOoCbOw3KHcIbb\nUFWt7X94BeKwOwhjjImSr43UQN1YMjbGGFO+FVnFpKq5wLXAKPd1I6DU2ySMMcb4K5oZ5TLcTfuw\nGeWMMabCsxnljDHGhGUzyhljjAnLZpQzxhgTls0oZ4wxFZhvM8qJSDywTFU7xBpccbECwhhjoufb\nk9Rut9a1IpISU2TGGGPKLS+9mGoAK0Tkc5zpRgFQ1X6+RWWMMabUeSkgHjmeE4hID+BZnLuVyar6\nRMj+K4GHcXpG5QJ/VNVFx3NOY4wxx89rI3UToLWq/p+IVAXiVXWvh+PigJ9wZqTbDCwB+qvqyqA0\nCaq6z319KvB3VW0VJi9rgzDGmCj5OpqriAwF5gCvuJua4swR4UVnYJWqZqnqYWAG0Cc4QX7h4KoB\n/OYxb2OMMT7y8hzEnUAXYDeAqv4ENPCYfwqwMWh9k7utABHpKyIrgA/d8xljjCllXtogDqjqIRHn\nDsXt+lqsVPU94D0R6Qq8AbQNl27s2LGB1+np6aSnpxd3KMYYU65lZmaSmZlZLHl5mQ/iaeAX4CZg\nOHA7TrXR6CIzF+kCjFXVHu76fThzSUR8EltE1gCdVXVbyHZrgzDGmCj5PaPcH4EcYCVwF/AR8GeP\n+S8BWolImjvAX3+c9owAEWkZ9LojQGjhYIwxpuRFrGISkYWqeinwsKr+CXgx2sxVNVdERgALOdrN\ndYWIDHN26yTgahEZjDNb3V7g+ljeiDHGmOIVsYpJRH4AbgSmAtfhjMMUoKrL/A4uJB6rYjLGmCj5\nMhaTiFwP3IzTg2kpBQsIVdVusZwwVlZAGGNM9PyakzpLVS8RkUdV1WubgzHGmAqisEbqF9x/e5ZE\nIMYYY8qWwu4gckXkr0CKiDwTulNVR/oXljHGmNJWWAFxBXApcDmwvGTCMcYYU1Z4eVDuLFX9qoTi\nKSwOa6Q2xpgo+dWL6R5VfVpEJgDHJCrpKiYrIIwxJnp+9WJa4/5b4vNPG2OMKX2e5oMoC+wOwhhj\noufbWEwicoOIfCEiu9zlPyIyMLYwjTHGlCeFjcU0CGegvnuAr3GepO4IPCnOz/m3SiZEY4wxpaGw\nRurPgUGquiZkewtgmqp2KYH4gs9rVUzGGBMlv6qYaoYWDgCquhaoGcvJjDHGlB+FFRD7C9m3r5B9\nxhhjKoDCqpj24UwSdMwuoI2qVvczsDDxWBWTMcZEya/nIE6NMR5jjDEVgD0HYYwxFZjfc1IbY4w5\nAVkBYYwxJqyIBYSI/FVEeotIQkkGZIwxpmworBfT+TizyV0E7AEWAPNVtVTmhrA2CGOMiZ4vw32H\nnKA+cBlOgXEy8CVOYTE7lpPGwgoIY4yJnu8FRMjJBOgM9FDVcbGcNBZWQBhjTPRKtIAoLVZAGGNM\n9KybqzHGmGJnBYQxxpiwiiwgRKSaiIwWkZfc9VYi0tP/0IwxxpQmL3cQr+IM0NfVXd8MPOZbRMYY\nY8oELwVEa1V9DDgMoKr7cAoMT0Skh4isFJGfRGRUmP0DReRbd1ksIjZIoDHGlAFeCohDIlIVUAAR\naQ4c8pK5iMQBz+M8Q9EBGCAiJ4ckWwt0U9XTgUeAv3mM3RhjjI8KG+4730PAfKCJiEwFLgR+5zH/\nzsAqVc0CEJEZQB+C5plQ1f8Epf8PkOIxb2OMMT4qtIBwH4r7FrgWOA+naun/qeqvHvNPATYGrW/C\nKTQiuRmY5zFvY4wxPiq0gFBVFZF/quopwPt+BiIi3YGbONoYfoyxY8cGXqenp5Oenu5nSMYYU+5k\nZmaSmZlZLHkV+SS1iLwJPK2qS6POXKQLMFZVe7jr9+GUO0+EpDsNmIUzfMeaCHnZk9TGGBMlv6Yc\nzXcmsERE1gB7caqZVFU7ejh2CdBKRNKALUB/YEBwAhFpilM4ZEQqHIwxxpQ8LwXElbFmrqq5IjIC\nWIjTY2qyqq4QkWHObp0EPADUBv7qtnkcVtXC2imMMcaUAC9VTI3DbVfVzb5EFDkOq2Iyxpgo+Tqa\nq4iswHkGQoCqQCqwRlXbxnLCWFkBYYwx0fO1DUJV24WcrDNOd1RjjDEVWNSjuarqF0AXH2IxxhhT\nhhR5ByEidwatxgFnAb/4FpExxpgywUsvpnpBr48A/wLe9SccY4wxZYWXAmKpqs4O3iAi/YDZEdIb\nY4ypALz0Yvo69KE4EflKVc/yNbJj47BeTMYYEyVfejGJyGVADyBFRJ4J2pUE5MVyMj80a9aMrKys\n0g7DmGKRlpbG+vXrSzsMY4DCq5h+Bb4HDgDLg7bnAPf5GVQ0srKysDsLU1E4gwkYUzZ4qWKqqqoH\nSiiewuIIW8Xk3j6VQkTGFD/7PJvi5vdgfSki8ijQHudJagBUtU0sJzTGGFM+eHlQ7jVgCs5QGz2B\nd4C3fYzJGGNMGeClgEhQ1QUAqrpGVe/HKSiMMcZUYF6qmA6KSBywRkR+D2QDif6GZYwxprR5uYP4\nA1AduBM4H2egvqF+BlWRNGvWjKpVq7J9+/YC288880zi4uLYsGFDicUybdo0EhMTSUpKIiEhgfj4\neJKSkgLbyrMFCxbQunXr0g7DmAql0AJCROKBq1Q1R1U3qGqGqvZR1X+XUHzlnojQvHlzpk+fHtj2\n/fffs3///hLv0jhw4EBycnLYvXs38+bNIyUlhd27dwe2lVWqWmTPHlU9ruuZm5sb87HGVFSFFhCq\nmgt0L6FYKqyMjAymTp0aWJ86dSpDhgwpkObQoUPce++9pKWl0ahRI4YPH87BgwcB2LlzJ71796Z+\n/frUqVOH3r17k52dHTi2e/fuPPjgg3Tt2pWkpCR69OhxzB2LV5s2baJv377Uq1ePVq1a8fLLLwf2\njR49mkGDBtG/f38SExM566yzWLduHQ899BD16tWjRYsWfPzxx4H05557Lg8++CCdOnUiOTmZa6+9\nlpycnMD+Tz/9lC5dupCcnEynTp347LPPChw7ZswYunTpQvXq1dmyZQuTJk2iXbt2JCUl0aZNG6ZM\nmQLA9u3b6devH2vXrg3cDe3YsYMBAwbw2GOPBfIMvcto1KgRTz/9NKeccgo1a9YEYOPGjRHfvzEn\nGi9VTF+JyGwRGSAiV+YvvkdWgXTp0oWcnBx+/PFH8vLyePvttxk0aFCBX8WjRo1i9erVLFu2jNWr\nV5Odnc1DDz0EQF5eHkOHDmXjxo1s2LCBhIQERowYUeAc06dPZ+rUqWzdupWDBw8yfvz4qOPMy8uj\nV69edO3alZ9//pn58+fz+OOP8+mnnwbSvPfeewwfPpxdu3bRunVrunfvTo0aNfjll18YOXIkt912\nW4E833jjDaZPn052djYHDx5k5MiRAKxfv56rrrqKxx9/nB07dvDII4/Qt29fdu3aFTj2rbfe4s03\n3yQnJ4cGDRrQuHFjFixYwO7du3nppZe4/fbbWbFiBbVr1+bvf/87LVq0CNwNJScnh32PoXcZ77zz\nDh999BHbtm0jLy+Pyy+/vND3b8yJxEsBkQjsBXoB17rLNX4GVdxEjn85Xvl3Ef/85z9p164djRsX\nnMn1b3/7GxMmTKBmzZpUr16d++67L1AtVbt2ba666iqqVKlC9erVGT16NJ988kmB42+66SZatmxJ\nlSpVuO666/jmm2+ijnHx4sUcPHiQe++9l/j4eFq1asWNN97IjBkzAmkuvvhiunXrRlxcHNdccw17\n9+5l5MiRxMXF0b9/f3788cfAnU9+XK1btyYhIYFx48YF8nr99de5+uqr6d7duUHt0aMH7du3Z+HC\nhYFjb775Zlq1akV8fDzx8fFcccUVNG3aFICLLrqICy+8kMWLF0f9PoONHDmSBg0aUKVKFU/v35gT\niZcZ5TJKIhA/lYUHUwcNGkS3bt1Yt24dgwcPLrBv69at7Nu3j7POOjr+YV5eXuAOY//+/dx9990s\nWLCAnTt3oqrs2bOnQL17w4YNA8cmJCSwZ8+eqGPMyspi3bp11K5dG3Dq9fPy8rjkkksCaRo0aBB4\nXa1aNerVq1dgXVXZu3cvVapUASA1NTWwPy0tjX379pGTk0NWVhbTp0/n3XffDZzryJEjbNmyJZA+\n+FiAOXPm8Oijj7J69Wry8vLYv38/3bp1i/p9BmvSpElU79+YE4mXCYNaAS8ADVX1dBE5DbhcVR/3\nPboKpGnTpjRv3px58+bx6quvFthXt25dEhISWL58OY0aNTrm2KeffppVq1axZMkS6tWrx7fffkvH\njh2Pu2E2VGpqKu3atePbb7+NOY/QeDZu3Bh4nZWVRUJCAomJiaSmpnLLLbfw3HPPecpr3759XHfd\ndcyePZuePXsiIvTs2TNQiIa7DtWrV2ffvn2B9eDCJ9w5iuP9G1OReKliegUYx9ERXL8DBvkWUQX2\n6quvsmjRIqpVq1Zgu4hwyy23cPfdd7N161YAsrOzA9UtOTk5VKtWjaSkJLZv387YsWN9ia9r164A\nPPfccxw8eJAjR47w3XffsXTpUs95hPY2eu2111i1ahV79uxh3Lhx9O/fH4AhQ4bw7rvvsmjRosDd\nwKJFi/j111/D5rt//36OHDkSuGOZM2cOmZmZgf0NGjTg119/Ze/evYFtZ5xxBnPnzmXXrl1kZ2fz\n/PPP+/7+jalIvBQQ1VU10L3EHTHvsH8hVSzBv1CbN29Ox44dw+574oknaNWqFV26dKFWrVpceuml\n/PTTTwDcfffd7Nu3j7p163LeeefRq1eviOc4HpUqVeLDDz/ks88+Iy0tjQYNGjB8+PACX7pFCY0l\nIyODAQMGkJqaSqVKlQKN582bN2fWrFmMGTOGunXr0rx5cyZOnEheXl7YfOrUqcP48eO54oorqFu3\nLnPmzOHyyy8P7D/99NO58sorSUtLo3bt2uzcuZOhQ4fSsmVL0tLSuPLKKxk4cGChsRbH+zemIvEy\nmut84DZglqp2FJG+wO9VtUdJBBgUh43mWs6ce+653HHHHcd8MZvI7PNsipvfo7mOACYDJ4tIFrAF\n6B/LyYwxxpQfXnoxrQYuEpGaOHccO/0Py1QENvmNMeWblyqmZOABoCugwGLgEVXd4X94BeKwKiZT\n4dnn2RS346li8tJIPQNnmtEbcHov7cbmgzDGmArPSwGRoqpjVHWVu4wDGhd5lEtEeojIShH5SURG\nhdnfVkQ+E5EDIjIymuCNMcb4x0sB8ZGIBIbWEJF+wD+9ZO7OI/E8cBnQARggIieHJNsG3AE85Sli\nY4wxJcJLATEYeEdEDorIIWAmcKOI7BCRooYM7QysUtUsVT2MU13VJziBqv6mql8BR2KI3xhjjE+8\ndHOtexxwM9b6AAAXWElEQVT5pwAbg9Y34RQaxhhjyrgi7yDcOSHa4lQTXZ6/qGquu88cp9tuu41H\nH300sP7iiy/SsGHDwLwG//73v2nTpg1JSUnMmTOnFCON3YEDB+jduze1atXi+uuvL+1wjDEeeBms\n729AJ+AHjo7HpICXb6psoGnQehN3W0yCxyBKT08nPT091qxKTLNmzfj111+pXLky8fHxtG/fnoyM\nDG699dbAcwIvvvhiIP2RI0e45557+OKLLzjllFMAGDNmDHfeeecxc0CUJzNnzmTr1q3s2LHDno8w\nxkeZmZkFxik7Hl6qmLoC7cM+hFC0JUArEUnj6BPYAwpJX+g3h1+D1PlJRPjggw/o3r07OTk5fPzx\nx9x5553897//PWZUV4Cff/6ZgwcP0q5du8C2rKws2rdvH9P5c3NziY+Pjzn+4pKVlUWbNm0iFg5l\nJU5jyrvQH8/jxo2LPbP8+X4jLcDrQNui0hVyfA/gR2AVcJ+7bRhwq/u6AU47xU5gO7ABqBEmHw0n\n0vayolmzZvrRRx8V2PbFF19oXFycLl++XFVVb7zxRn3ggQf0p59+0urVq2tcXJwmJibqxRdfrC1b\nttS4uDitVq2aJiYm6qFDh3TXrl36u9/9Ths1aqRNmjTR+++/X/Py8lRV9bXXXtPzzz9f//CHP2id\nOnX0gQceUFXVyZMna7t27bR27drao0cPzcrKCsQjIvrSSy9p69atNTk5WW+//fYC8U6aNEnbtWun\niYmJ2qFDB126dKmqqm7evFmvvvpqrVevnrZo0UInTpwY9hqMGTNGTzrpJK1cubImJibqq6++GjbO\nvLw8ffjhhzUtLU0bNGigQ4YM0V27dqmq6vr161VEdMqUKZqamqp16tTRF198UZcsWaKnnXaaJicn\n64gRI4rhL1a6yvrn2ZQ/7mcqtu/vIhNAN2AXsBz4GlgKfB3rCWMOtAIVEKqqTZs21ZdeeklVjxYQ\nqs4XYVxcXOALPz+PRYsWBdb79u2rt912m+7fv1+3bt2q55xzjk6aNElVnQKiUqVK+sILL2hubq4e\nOHBA33vvPW3durX++OOPmpubq48++qied955gfxERHv37q27d+/WDRs2aL169XTBggWqqvrOO+9o\nkyZN9KuvvlJV1TVr1uiGDRs0Ly9PzzrrLH3kkUf0yJEjum7dOm3ZsqUuXLgw7HUYO3asZmRkBNbD\nxTl58mRt3bq1rl+/Xvfu3av9+vULHJNfQNx222168OBBXbhwoVapUkX79u2rv/32m2ZnZ2v9+vX1\nk08+if6PVIaU9c+zKX+Op4Dw0s31VeAmoC9Hpxu9NuZbFgNA48aN2b49ci9hDanRy1//9ddfmTdv\nHhMmTKBq1arUrVuXu+++OzA9KUBKSgrDhw8nLi6OKlWq8PLLLzN69GjatGlDXFwc9913H998802B\nyXxGjx4dmMine/fugSlLJ0+ezB//+MfAMOUtWrQgNTWVJUuW8Ntvv/HnP/+Z+Ph4mjVrxs033xzV\n9JyhcU6bNo2RI0eSlpZGQkICjz/+ODNmzCgwBPiDDz7ISSedxCWXXEKNGjW44YYbqFOnDo0bN+aC\nCy6wuRuMKUZe2iB+U9XZvkdygsnOzg5MbRmNrKwsDh8+HJh5Lr+kz5+rGY6dqjMrK4u77rqLe+65\nJ3CMiJCdnR1IGzyVaPCUpRs3bqRly5Zh4wh+D+pOzxnNFKChcW7evJm0tLTAelpaGkeOHOGXX34J\nbKtfv37gdbVq1Y5Zj2WqVWNMeF4KiC9F5HXgH0BgNnpVLZ/9LcuAJUuWsHnzZi644IKoj01NTaVq\n1aps27YtYoNv6PamTZty//33M2BAYf0DIp9vzZo1Ybe3aNGCH3/8Meo8I8XZuHFjsrKyAutZWVlU\nrlyZBg0aFLjbMcaUDC9VTDVxehddiVO1lF/NZKKUk5PD3LlzGTBgABkZGRF7JoVWLwVr2LAhl156\nKX/4wx/IyclBVVm7di2ffPJJxGOGDRvGY489xg8//ADArl27mDlzpqeYb775ZsaPH8/XX38NwJo1\na9i4cSOdO3cmMTGRJ598kgMHDpCbm8vy5cv58ssvPeUbzoABA5gwYQLr169nz549/PnPf6Z///7E\nxTkf08KuizGm+HmZDyKjJAKpyHr37k2lSpWIi4ujffv23HvvvQwbNixi+tBf1qHrr7/+OqNGjaJ9\n+/bs2bOHFi1aMGrUMeMgBvTt25e9e/fSv39/NmzYQM2aNbnkkku45pprijzfNddcw/bt2xk4cCCb\nN2+mWbNmvPHGG6SmpjJ37lxGjhxJ8+bNOXToEG3btuWRRx7xfF1CDR06lC1bttCtWzcOHjxIjx49\nmDhxoufrYs9XGFO8vMwH0Qp4AWioqqeLyGk4T1I/XhIBBsWh4WK18fNNRWKfZ1Pc/J4P4hVgHEef\nov4OZ14IY4wxFZiXAqK6qn6Wv+L+jD/sX0jGGGPKAi8FxDYRaY4z/hIi0hf42deojDHGlDovBcQI\nYDJwsohkAfcBv/c1qmI2NnMsMk6OWcZmjvWUPlI6Y4ypyCI2UotIv+AH5ESkppt+Z0kFFxKPNVIX\nYurUqbzyyit8+umnUR+7ceNGOnTowK5du0qkJ1D37t3JyMhg6NChvp+rvLHPsylufjVS3x+8oqq7\nSqtwMN54/XJv3rw5ixYtCqynpqaye/fuctdN9OOPPz7maeyS8s0339CpUyeqV6/O2Wefzbfffhsx\n7U033USVKlVISkoiMTGRpKQkKwRMueClismYMil/yJCSdvjwYfr27cvgwYPZuXMngwcPpk+fPhw5\nEnnW3FGjRrF7925ycnLKZWFsTkyFFRAni8iyMMt3IrKsxCKsYO6++26aNm1KzZo1Ofvss1m8eHFg\n37hx47j++usZMmQISUlJnHrqqYEnmAGeeOIJWrVqRVJSEqeccgrvvfde2HOMGDGCe++9t8C2Pn36\n8NxzzzF48GA2bNhA7969SUpKYvz48WRlZREXFxcYFG/Hjh0MHTqUlJQU6tSpQ79+/cKeZ82aNaSn\np1OrVi3q169fYCiPzz77jM6dO5OcnMw555zD559/HtP1eu2112jfvj1JSUm0atWKSZMmAbBv3z56\n9erF5s2bA7/Kf/65YN+JL7/8koYNGxb4tT579mzOOOOMmGLJl5mZSW5uLnfeeSeVK1fmjjvuQFUL\n3JUZUyFEGuYVZ3jvtEhLrMPHxrpQTof7DvXWW2/pjh07NDc3V5955hlt2LChHjx4UFWdIbGrVaum\n8+fP17y8PB09erR26dIlcOzMmTP1559/VlVnGO7q1asH1l977TW94IILVNWZbyIlJSVw3G+//abV\nq1fXrVu3quqxw4fnDzGem5urqqq9evXS/v37665du/TIkSMRh9AeMGCAPvbYY6qqevDgQf33v/+t\nqqrbt2/X5ORkfeuttzQ3N1enT5+uycnJun37dlVVTU9P18mTJ3u6Xh9++KGuW7dOVVU/+eQTTUhI\nCMxHkZmZqampqYUe36FDB50/f35g/aqrrtIJEyaoquq0adO0Vq1ampycrLVq1SrwOjk5WTdu3Bg2\nzwkTJmivXr0KbOvdu7c+88wzYdPfeOONWqdOHa1Tp4526tRJZ82aFTHe8vZ5NmUffswHASyNNVM/\nlopSQIRKTk7WZcuWqapTQFxyySWBfT/88IMmJCREPPaMM87QOXPmqGrBAkJVtX379vqvf/1LVVWf\nf/55vfzyywP7QueoCC4gNm/erPHx8YGJegozePBgHTZsmG7atKnA9jfeeEPPOeecAtvOPfdcnTp1\nqqpGV0CE6tu3b2BiIi8FxF/+8he94YYbVFV127ZtmpCQEChUY/Xwww/rgAEDCmy74YYbdNy4cWHT\nL126VLdv3665ubn64YcfamJion722Wdh05b3z7Mpe46ngCisiunfftyxnOjGjx9P+/btSU5OJjk5\nmd27d/Pbb78F9jds2DDwOiEhgQMHDgSqfl5//XXOPPPMwLHLly8vcGywjIwM3nzzTQDefPNNMjK8\nDam1adMmateuTVJSUpFpn3rqKfLy8ujcuTOnnnoqU6ZMAY4dthucobuzs6OfjnzevHmce+651KlT\nh+TkZObNmxfxPYczaNAg5s6dy/79+3nnnXfo1q1bgaHNvUhMTAxUY23atIkaNWqwe/fuAml27dpF\nYmJi2OPPOOMMkpOTiYuLo2fPntxwww3Mnm0j6JuyL2IBoaojSjKQE8HixYt56qmnmDlzJjt27GDH\njh2ee7Rs2LCBW2+9lb/+9a+BYzt06BDx2IyMDN5//32WLVvGypUr6du3b2BfYQ2kqampbN++/Zgv\nwHDq16/PpEmTyM7O5qWXXmL48OGsXbuWxo0bs379+mPiT0lJKTLPYIcOHeKaa67hj3/8I1u3bmXH\njh307Nkz8J69NPSmpKTQpUsXZs2adUxBOW3atMAXf/ASXBiAMwpvfuNykyZN6NChA8uWFWyGW7Zs\nGR06dPD0vqwrqykvrBdTCcrJyaFy5crUqVOHQ4cO8dBDD5GTk1PoMflfJHv37iUuLo66deuSl5fH\nlClT+P777yMel5KSwllnnUVGRgZXX301VapUCexr2LAha9euDXuehg0b0rNnT4YPH87OnTs5cuRI\nxGcrZs6cGbgrqFWrFnFxccTFxdGrVy9WrVrFjBkzyM3N5e2332bFihX07t276IsU5NChQxw6dIi6\ndesSFxfHvHnzWLhwYWB/gwYN2LZtW5GFWUZGBk8++STff/99gQb3gQMHBr74g5fgwiCc9PR04uPj\n+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\nCev/A0hUSGM1F9aFAAAAAElFTkSuQmCC\n", + "text/html": [ + "" + ], "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -591,69 +400,26 @@ } ], "source": [ - "n = 3\n", - "arrMeanTemp = numpy.zeros(n)\n", - "arrError = numpy.zeros(n)\n", "\n", - "for i in range(n):\n", - " dt = tempadvDiff.get_max_dt()\n", - " \n", - " arrMeanTemp[i] = averageTemperature.evaluate()[0]\n", - " midTemp = temperatureField.evaluate_global((-1.,-0.5))\n", - " if rank == 0:\n", - " arrError[i] = abs(analyticsol(-0.5) - midTemp[0])\n", - " \n", - " tempadvDiff.integrate(dt)\n", - " \n", "\n", - "if rank == 0:\n", - " plt.plot(range(n),arrMeanTemp,label=\"Mean Temperature\")\n", - " plt.plot(range(n),arrError,\"--\",label=\"Difference from \\n analytic sol. at y=-0.5\")\n", + "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Velocity Calculated on Swarm\" )\n", + "figMaterial.append( glucifer.objects.Points(swarm, materialVelocity[1], pointSize=5.0) )\n", "\n", - " plt.legend(loc='best')\n", - " plt.xlabel('Time-step')\n", - " plt.ylabel('Mean Temperature / Difference from Analytic Sol.')\n", - " plt.ylim(0,0.6)\n", - " plt.title('Convergence Check')\n", - "\n", - " if savefigures:\n", - " plt.savefig(\"AvTemperatureTimestep.pdf\")\n" - ] - }, - { - "cell_type": "code", - "execution_count": 20, - "metadata": { - "collapsed": false - }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "#Write to h5 file\n", - "savedmesh = mesh.save(\"input/1_13_Groundwater_Flow/mesh.h5\")\n", - "temperatureField.save(\"input/1_13_Groundwater_Flow/temperature.h5\",meshHandle=savedmesh)" + "figMaterial.append( glucifer.objects.Mesh(mesh))\n", + "figMaterial.show()\n", + "\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Here is our temperature field. Does it look perturbed?*" + "Plot the same velocity field as vectors, over the pressure field solution." ] }, { "cell_type": "code", - "execution_count": 21, + "execution_count": 14, "metadata": { "collapsed": false }, @@ -661,7 +427,7 @@ { "data": { "text/html": [ - "" + "" ], "text/plain": [ "" @@ -672,33 +438,32 @@ } ], "source": [ - "figMaterial = glucifer.Figure( figsize=(800,400),title=\"Temperature Field\" )\n", - "figMaterial.append( glucifer.objects.Surface(mesh,temperatureField ))\n", - "if size == 1:\n", - " figMaterial.show()\n", - "if savefigures:\n", - " figMaterial.save_image(\"TemperatureField.png\")" + "figMaterial = glucifer.Figure( figsize=(800,400),title=\"Ground-Water Pressure Field and Velocity Vectors\" )\n", + "figMaterial.append(glucifer.objects.Surface(mesh,gwPressureField,onMesh=True))\n", + "scale = 0.03\n", + "figMaterial.append(glucifer.objects.VectorArrows(mesh,velocityField,scaling=50,arrowHead=0.3))\n", + "figMaterial.show()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ - "*Plot profiles of temperature with depth at the left wall, centre and right wall. The walls should agree with the analytic solutions with and without advection ... unless you're playing around with the geometry. Then they're a useful reference!*" + "We can also compare the velocity calculated on the swarm to an analytical solution." ] }, { "cell_type": "code", - "execution_count": 22, + "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "data": { - "image/png": "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\n", + "image/png": "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\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -706,59 +471,54 @@ } ], "source": [ - "n = 50\n", - "arrY = numpy.linspace(-1.,0.,n)\n", - "arrT = numpy.zeros(n)\n", - "\n", - "if rank == 0:\n", - " plt.clf()\n", - "\n", - "for xpos in [-1.,0.,1.]:\n", - " arrT = numpy.zeros(n)\n", - " for i in range(n):\n", - " arrT[i] = temperatureField.evaluate_global((xpos,arrY[i]))\n", "\n", - " if rank == 0:\n", - " plt.plot(arrT,arrY,label=\"x=%i\" %xpos)\n", "\n", + "x = -1.\n", + "n = 30\n", + "arrYsample = numpy.linspace(-1+(1./resY),0.,resY)\n", + "arrY = numpy.linspace(-1,0.,n)\n", "\n", - "# Analytic Solution\n", - "if rank == 0:\n", - " arrY = numpy.linspace(-1.,0.,10)\n", - " arrAnalytic = numpy.zeros(10)\n", - " for i in range(10):\n", - " arrAnalytic[i] = analyticsol(arrY[i])\n", + "arrP = numpy.array(velocityField[1].evaluate_global(numpy.array(zip(numpy.ones(len(arrYsample))*x,arrYsample))))\n", "\n", - " plt.scatter(arrAnalytic,arrY,label=\"Analytic Advection\",lw=0,c=\"Blue\")\n", - " plt.scatter(-1. * arrY,arrY, label=\"Analytic Non-Advect\",lw=0,c=\"Black\")\n", - "\n", - " plt.legend(loc=0,frameon=False)\n", - " plt.xlabel('Temperature')\n", + "if uw.rank() == 0:\n", + " plt.clf()\n", + " plt.scatter(arrP,arrYsample,lw=0,alpha=0.5,label=\"Numerical\")\n", + "\n", + " S = 1.\n", + " La = -1. * interfaceY\n", + " Lb = 1. + interfaceY\n", + " dP = maxgwpressure\n", + " midPressure = (dP/Lb - S + Ka/Kb * S) / (1./Lb + Ka/Kb/La)\n", + "\n", + " arrVel = numpy.zeros(len(arrY))\n", + "\n", + " for i in range(len(arrY)):\n", + " if arrY[i] > interfaceY:\n", + " arrVel[i] = (-midPressure / -La - 1.) * Ka\n", + " else:\n", + " arrVel[i] = (-(dP - midPressure)/-Lb - 1.) * Kb\n", + "\n", + " plt.plot( (arrVel) ,arrY,c=\"black\",label=\"Analytical\")\n", + "\n", + " plt.ylim(-1,0.)\n", + " avAnVel = numpy.average(arrVel)\n", + " plt.xlim(-0.25*avAnVel + avAnVel,0.25*avAnVel+avAnVel)\n", + " plt.ticklabel_format(style='sci', axis='x', scilimits=(0,0))\n", + " plt.legend()\n", + " plt.xlabel('Vertical Velocity')\n", " plt.ylabel('Depth')\n", "\n", - " plt.xlim(0,1)\n", - " plt.ylim(-1,0)\n", - " plt.title('Temperature Profiles')\n", - " if size == 1:\n", - " plt.show()\n", - " if savefigures:\n", - " plt.savefig(\"Geotherms.pdf\")" + " plt.savefig(\"VelocitySolution.pdf\")\n" ] }, { - "cell_type": "markdown", + "cell_type": "code", + "execution_count": null, "metadata": { "collapsed": true }, - "source": [ - "**Now go feel free to go back and make some changes:**\n", - "\n", - "1. Lower the maximum groundwater pressure until the perturbed geotherm is colder than the linear geotherm\n", - "2. Remove the low permeability material completely (i.e. give everything a high permeability) and check that the analaytical solution almost exact. Then explore how wide the high permeablity zone has to be for it to be effectively 1D\n", - "3. Go to where the materials are set up and make some more complicated geometries.\n", - "4. Set up a horizontal groundwater pressure gradient, make sure the thermal diffusivity is homogeneous over the domain and turn off gravity. You will need to alter the boundary conditions. If done correctly, the temperature field should not be perturbed.\n", - "5. What does the ratio of hydraulic diffusivity to storage control?" - ] + "outputs": [], + "source": [] } ], "metadata": { @@ -777,7 +537,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", - "version": "2.7.11" + "version": "2.7.13" } }, "nbformat": 4, diff --git a/docs/examples/1_16_Groundwater_Heat_Advection.ipynb b/docs/examples/1_16_Groundwater_Heat_Advection.ipynb new file mode 100644 index 000000000..ffaac3ef1 --- /dev/null +++ b/docs/examples/1_16_Groundwater_Heat_Advection.ipynb @@ -0,0 +1,785 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import underworld as uw\n", + "import glucifer\n", + "import numpy\n", + "import matplotlib.pyplot as plt\n", + "import mpi4py\n", + "\n", + "uw.matplotlib_inline()\n", + "plt.ion()\n", + "\n", + "comm = mpi4py.MPI.COMM_WORLD\n", + "rank = comm.Get_rank()\n", + "size = comm.Get_size()\n", + "\n", + "# Whether or not to save figures to files in the current directory.\n", + "# Mainly useful when not using a notebook or for comparisons.\n", + "savefigures = False" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### Groundwater Flow\n", + "\n", + "Underworld can efficiently solve the diffusion-advection equation and can set up as many simultaneous instances of it in a model as we would like. Heat-flow and groundwater flow are both described by this equation, so we can set these up and couple them, to model temperature advection by groundwater.\n", + "\n", + "**Temperature Diffusion-Advection Equation**\n", + "\n", + "$\\frac{\\partial T} {\\partial t} = \\kappa \\nabla^2 T + G$\n", + "\n", + "\n", + "where: $\\kappa = \\frac{k}{C_p \\rho}$\n", + "\n", + "($\\kappa$ - thermal diffusivity, $T$ - temperature, $t$ - time, $G$ - groundwater advection term, $C_p$ - heat capacity, $\\rho$ - rock density)\n", + "\n", + "**Groundwater Pressure Diffusion Equation**\n", + "\n", + "$\\frac{\\partial H} {\\partial t} = \\kappa_H \\nabla^2 H + F$\n", + "\n", + "where: $\\kappa_H = \\frac{k_H}{\\mu S}$\n", + "\n", + "$F = \\frac{g}{S} \\frac{\\partial \\rho_w}{\\partial y}\\ \\ \\ $assuming constant $\\rho_w$, $\\ F=0$\n", + "\n", + "($\\kappa_H$ - hydraulic diffusivity, $H$ - groundwater pressure, $k_H$ - hydraulic permeability, $\\mu$ - water viscosity, $S$ - specific storage, $g$ - gravitational accelleration, $\\rho_w$ - density of water)\n", + "\n", + "**Groundwater Flow Equation**\n", + "\n", + "$ q = \\frac{k_H}{\\mu}\\left(\\nabla H + \\rho_w g\\right) $\n", + "\n", + "\n", + "**Coupling**\n", + "\n", + "$G = -\\nabla T \\cdot \\frac{\\rho_w C_w}{\\rho C} q$\n", + "\n", + "($C_w$ - heat capacity of water)\n", + "\n", + "Coupling is implemented by handing an 'effective velocity field', $\\frac{\\rho_w C_w}{\\rho C} q$ to the temperature diffusion-advection solver.\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "---\n", + "\n", + "*Set up mesh and fields*" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "\n", + "elementType = \"Q1/dQ0\"\n", + "resX = 16\n", + "resY = 32\n", + "mesh = uw.mesh.FeMesh_Cartesian( elementType = (elementType), \n", + " elementRes = (resX, resY), \n", + " minCoord = (-1., -1.), \n", + " maxCoord = (1., 0.)) \n", + "\n", + "temperatureField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + "temperatureDotField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + "\n", + "gwPressureField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + "hydraulicDiffusivityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + "gwPressureDotField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=1 )\n", + "\n", + "velocityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=2 )\n", + "zerovelocityField = uw.mesh.MeshVariable( mesh=mesh, nodeDofCount=2 )\n", + "\n", + "domainVolume = (mesh.maxCoord[1] - mesh.minCoord[1]) * (mesh.maxCoord[0] - mesh.minCoord[0])\n", + "averageTemperature = uw.utils.Integral(fn = temperatureField / domainVolume,mesh= mesh,integrationType=\"volume\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Set up the types of boundary conditions*" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "iWalls = mesh.specialSets[\"MinI_VertexSet\"] + mesh.specialSets[\"MaxI_VertexSet\"]\n", + "jWalls = mesh.specialSets[\"MinJ_VertexSet\"] + mesh.specialSets[\"MaxJ_VertexSet\"]\n", + "insideNodes = []\n", + "for i in range(mesh.nodesLocal):\n", + " if i not in iWalls and i not in jWalls:\n", + " insideNodes.append(i)\n", + "\n", + "\n", + "\n", + "temperatureBC = uw.conditions.DirichletCondition( variable = temperatureField, \n", + " indexSetsPerDof = ( jWalls) )\n", + "\n", + "gwPressureBC = uw.conditions.DirichletCondition( variable = gwPressureField, \n", + " indexSetsPerDof = ( jWalls) )\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Set initial conditions and the values of the boundary conditions*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**This lower ground-water pressure is something that you can change. You can lower it until gravity dominates.**" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "#Lower groundwater pressure boundary condition\n", + "# this value is relative to gravity\n", + "maxgwpressure = 2." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Set up initial conditions. This includes whether or not you want to read in an existing temperature field. We will by default, because we will only run a couple of time steps." + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "readTemperature = True\n", + "\n", + "yCoordFn = uw.function.input()[1]\n", + "\n", + "if readTemperature:\n", + " temperatureField.load(\"input/1_13_Groundwater_Flow/temperature.h5\", interpolate=True)\n", + "else:\n", + " initialFn = -1. * yCoordFn\n", + " temperatureField.data[:] = initialFn.evaluate(mesh)\n", + "\n", + "initialFn = -1. * maxgwpressure * yCoordFn\n", + "gwPressureField.data[:] = initialFn.evaluate(mesh)\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial Temperature Field\" )\n", + "figMaterial.append( glucifer.objects.Surface(mesh,temperatureField ))\n", + "if size == 1:\n", + " figMaterial.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Set up swarm*" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "swarm = uw.swarm.Swarm( mesh=mesh )\n", + "swarmLayout = uw.swarm.layouts.GlobalSpaceFillerLayout( swarm=swarm, particlesPerCell=10 )\n", + "swarm.populate_using_layout( layout=swarmLayout )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Assign materials to particles*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "** Here we are deciding on the distribution of different materials. The benchmark is for a large region which extends from the bottom to the top of the domain, in this case on the left hand half of the model. Once you are happy with the benchmark, feel free to change the model geometries!** " + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "materialIndex = swarm.add_variable( dataType=\"int\", count=1 )\n", + "\n", + "materialPorous = 0\n", + "materialImpermeable = 1\n", + "\n", + "xCoordFn = uw.function.input()[0]\n", + "yCoordFn = uw.function.input()[1]\n", + "\n", + "conditions = [ (yCoordFn > 0., materialPorous),\n", + " ( xCoordFn < 0. , materialPorous),\n", + " ( True , materialImpermeable )]\n", + "\n", + "\n", + "materialIndex.data[:] = uw.function.branching.conditional( conditions ).evaluate(swarm)\n", + "\n", + "\n", + "\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Visualise the materials we have just assigned*" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial Material Distribution\" )\n", + "figMaterial.append( glucifer.objects.Points(swarm, materialIndex, pointSize=4.0) )\n", + "if size == 1:\n", + " figMaterial.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Assign material properties*" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "**Here we have material properties which are chosen relative to the thermal diffusion time-scale. Leave the thermal diffusivity as 1, but you can change the maximum hydraulic diffusivity to control their relative time-scale (along with the chosen pressure gradient above). Feel free to change it!**\n", + "\n", + "**The storage capacity effectively controls the ratio of groundwater pressure diffusion to groundwater flow. The ratio of $\\rho_w c_w / \\left( \\rho c \\right)$ controls the rate of energy transfer from the water to the rock matrix. $\\rho_w$ also affects the gravity term in the ground-water flow equation ... denser water will sink in the absence of an upward pressure decrease.**" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "maxHydDiff = 1.\n", + "hydraulicDiffusivityMap = { materialPorous : maxHydDiff, \n", + " materialImpermeable : 1e-5}\n", + "hydraulicDiffusivityMapFn = uw.function.branching.map( fn_key = materialIndex, mapping = hydraulicDiffusivityMap )\n", + "\n", + "#Hydraulic storage capacity\n", + "Storage = 1.\n", + "\n", + "rho_water = 1.\n", + "rho_rock = 2.5\n", + "\n", + "c_w = 4000.\n", + "c = 1250.\n", + "\n", + "# g = 1.\n", + "g = uw.function.misc.constant((0.,1.))\n", + "\n", + "\n", + "thermalDiff = 1.\n", + "thermalDiffusivityMap = { materialPorous : thermalDiff, \n", + " materialImpermeable : thermalDiff}\n", + "thermalDiffusivityMapFn = uw.function.branching.map( fn_key = materialIndex, mapping = thermalDiffusivityMap )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Setup groundwater equations*" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "\n", + "gwadvDiff = uw.systems.SteadyStateHeat( temperatureField = gwPressureField, fn_diffusivity = hydraulicDiffusivityMapFn,conditions=[gwPressureBC])\n", + "\n", + "gwsolver = uw.systems.Solver(gwadvDiff)\n", + "\n", + "hydraulicProjector = uw.utils.MeshVariable_Projection(hydraulicDiffusivityField,hydraulicDiffusivityMapFn)\n", + "hydraulicProjector.solve()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Gradients - needed for calculating ground-water flow and advection*" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tempGrad = temperatureField.fn_gradient\n", + "gwPressureGrad = gwPressureField.fn_gradient\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Ground-water Velocity*" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "gwVelField = -1.*rho_water / rho_rock * c_w / c *(g *rho_water + gwPressureGrad)* hydraulicDiffusivityField * Storage\n", + "velocityfieldProjector = uw.utils.MeshVariable_Projection(velocityField,gwVelField)\n", + "\n", + "velocityfieldProjector.solve()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figMaterial = glucifer.Figure( figsize=(800,400), title=\"Initial ground-water pressure and velocity vectors\" )\n", + "figMaterial.append( glucifer.objects.Surface(mesh,gwPressureField ))\n", + "figMaterial.append(glucifer.objects.VectorArrows(mesh,gwVelField,scaling=0.03))\n", + "if size == 1: \n", + " figMaterial.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Setup temperature advection-diffusion solver*" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "tempadvDiff = uw.systems.AdvectionDiffusion( temperatureField, temperatureDotField, \n", + " velocityField, \n", + " fn_diffusivity=thermalDiffusivityMapFn, conditions=[temperatureBC,] ) \n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "For a ground-water velocity $q$, this the following is an analytic solution to the 1D temperature diffusion-advection equation: $\\frac{d^2 T}{dy^2} + q'\\frac{dT}{dy} = 0$\n", + "\n", + "where: $q' = \\frac{\\rho_w c_w}{\\rho c} \\frac{q}{\\kappa}$\n", + "\n", + "The solution, assuming $H=0$ and $T=0$ at the surface and $H = H_{max}$ and $T=1$ at the base of the domain, is:\n", + "\n", + "$T(y) = \\alpha \\left(e^{q' y} - 1 \\right)\\ \\ \\ $ where: $\\alpha = \\left( e^{-q'}-1 \\right)^{-1}$ (you can check it's actually a solution)\n", + "\n", + "\n", + "We can use this to benchmark an effectively 1D part of the domain." + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "def analyticsol(y):\n", + " qp = rho_water / rho_rock * c_w / c * maxHydDiff / thermalDiff * Storage * (maxgwpressure - rho_water)\n", + " \n", + " if qp == 0.:\n", + " return -y\n", + " else:\n", + " return (numpy.exp(qp*y) - 1.) / (numpy.exp(-qp) -1. )" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "We solve for the groundwater pressure diffusion first, as it temperature-independent. Because the temperature advection-diffusion depends on groundwater flow, but not the other way round, we can solve for groundwater pressure first. There is no source term, so we can use the steady-state solver." + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [], + "source": [ + "\n", + "gwsolver.solve()\n", + "\n", + "velocityfieldProjector.solve()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figMaterial = glucifer.Figure( figsize=(800,400),title=\"Ground-Water Pressure Field and Velocity Vectors\" )\n", + "figMaterial.append(glucifer.objects.Surface(mesh,gwPressureField,))\n", + "scale = 0.03\n", + "figMaterial.append(glucifer.objects.VectorArrows(mesh,velocityField*scale,scaling=1.))\n", + "if size == 1:\n", + " figMaterial.show()\n" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Now solve for the temperature.*\n", + "\n", + "**This could certainly take a while to reach a steady-state. Look at the figures below and make sure that the mean temperature does not vary by the end of the loop. If the left hand wall of the model is homogeneous and is therefore effectively 1D, with purely vertical ground-water flow, check that this solution agrees with the analytic solution**" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "metadata": { + "collapsed": false, + "scrolled": true + }, + "outputs": [ + { + "data": { + "image/png": "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\nzwkTJmivXr0KbOvdu7c+88wzYdPfeOONWqdOHa1Tp4526tRJZ82aFTHe8vZ5NmUffswHASyNNVM/\nlopSQIRKTk7WZcuWqapTQFxyySWBfT/88IMmJCREPPaMM87QOXPmqGrBAkJVtX379vqvf/1LVVWf\nf/55vfzyywP7QueoCC4gNm/erPHx8YGJegozePBgHTZsmG7atKnA9jfeeEPPOeecAtvOPfdcnTp1\nqqpGV0CE6tu3b2BiIi8FxF/+8he94YYbVFV127ZtmpCQEChUY/Xwww/rgAEDCmy74YYbdNy4cWHT\nL126VLdv3665ubn64YcfamJion722Wdh05b3z7Mpe46ngCisiunfftyxnOjGjx9P+/btSU5OJjk5\nmd27d/Pbb78F9jds2DDwOiEhgQMHDgSqfl5//XXOPPPMwLHLly8vcGywjIwM3nzzTQDefPNNMjK8\nDam1adMmateuTVJSUpFpn3rqKfLy8ujcuTOnnnoqU6ZMAY4dthucobuzs6OfjnzevHmce+651KlT\nh+TkZObNmxfxPYczaNAg5s6dy/79+3nnnXfo1q1bgaHNvUhMTAxUY23atIkaNWqwe/fuAml27dpF\nYmJi2OPPOOMMkpOTiYuLo2fPntxwww3Mnm0j6JuyL2IBoaojSjKQE8HixYt56qmnmDlzJjt27GDH\njh2ee7Rs2LCBW2+9lb/+9a+BYzt06BDx2IyMDN5//32WLVvGypUr6du3b2BfYQ2kqampbN++/Zgv\nwHDq16/PpEmTyM7O5qWXXmL48OGsXbuWxo0bs379+mPiT0lJKTLPYIcOHeKaa67hj3/8I1u3bmXH\njh307Nkz8J69NPSmpKTQpUsXZs2adUxBOW3atMAXf/ASXBiAMwpvfuNykyZN6NChA8uWFWyGW7Zs\nGR06dPD0vqwrqykvrBdTCcrJyaFy5crUqVOHQ4cO8dBDD5GTk1PoMflfJHv37iUuLo66deuSl5fH\nlClT+P777yMel5KSwllnnUVGRgZXX301VapUCexr2LAha9euDXuehg0b0rNnT4YPH87OnTs5cuRI\nxGcrZs6cGbgrqFWrFnFxccTFxdGrVy9WrVrFjBkzyM3N5e2332bFihX07t276IsU5NChQxw6dIi6\ndesSFxfHvHnzWLhwYWB/gwYN2LZtW5GFWUZGBk8++STff/99gQb3gQMHBr74g5fgwiCc9PR04uPj\n+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\nCev/A0hUSGM1F9aFAAAAAElFTkSuQmCC\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n = 3\n", + "arrMeanTemp = numpy.zeros(n)\n", + "arrError = numpy.zeros(n)\n", + "\n", + "for i in range(n):\n", + " dt = tempadvDiff.get_max_dt()\n", + " \n", + " arrMeanTemp[i] = averageTemperature.evaluate()[0]\n", + " midTemp = temperatureField.evaluate_global((-1.,-0.5))\n", + " if rank == 0:\n", + " arrError[i] = abs(analyticsol(-0.5) - midTemp[0])\n", + " \n", + " tempadvDiff.integrate(dt)\n", + " \n", + "\n", + "if rank == 0:\n", + " plt.plot(range(n),arrMeanTemp,label=\"Mean Temperature\")\n", + " plt.plot(range(n),arrError,\"--\",label=\"Difference from \\n analytic sol. at y=-0.5\")\n", + "\n", + " plt.legend(loc='best')\n", + " plt.xlabel('Time-step')\n", + " plt.ylabel('Mean Temperature / Difference from Analytic Sol.')\n", + " plt.ylim(0,0.6)\n", + " plt.title('Convergence Check')\n", + "\n", + " if savefigures:\n", + " plt.savefig(\"AvTemperatureTimestep.pdf\")\n" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "#Write to h5 file\n", + "savedmesh = mesh.save(\"input/1_13_Groundwater_Flow/mesh.h5\")\n", + "temperatureField.save(\"input/1_13_Groundwater_Flow/temperature.h5\",meshHandle=savedmesh)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Here is our temperature field. Does it look perturbed?*" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "figMaterial = glucifer.Figure( figsize=(800,400),title=\"Temperature Field\" )\n", + "figMaterial.append( glucifer.objects.Surface(mesh,temperatureField ))\n", + "if size == 1:\n", + " figMaterial.show()\n", + "if savefigures:\n", + " figMaterial.save_image(\"TemperatureField.png\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Plot profiles of temperature with depth at the left wall, centre and right wall. The walls should agree with the analytic solutions with and without advection ... unless you're playing around with the geometry. Then they're a useful reference!*" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "metadata": { + "collapsed": false + }, + "outputs": [ + { + "data": { + "image/png": "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\n", + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "n = 50\n", + "arrY = numpy.linspace(-1.,0.,n)\n", + "arrT = numpy.zeros(n)\n", + "\n", + "if rank == 0:\n", + " plt.clf()\n", + "\n", + "for xpos in [-1.,0.,1.]:\n", + " arrT = numpy.zeros(n)\n", + " for i in range(n):\n", + " arrT[i] = temperatureField.evaluate_global((xpos,arrY[i]))\n", + "\n", + " if rank == 0:\n", + " plt.plot(arrT,arrY,label=\"x=%i\" %xpos)\n", + "\n", + "\n", + "# Analytic Solution\n", + "if rank == 0:\n", + " arrY = numpy.linspace(-1.,0.,10)\n", + " arrAnalytic = numpy.zeros(10)\n", + " for i in range(10):\n", + " arrAnalytic[i] = analyticsol(arrY[i])\n", + "\n", + " plt.scatter(arrAnalytic,arrY,label=\"Analytic Advection\",lw=0,c=\"Blue\")\n", + " plt.scatter(-1. * arrY,arrY, label=\"Analytic Non-Advect\",lw=0,c=\"Black\")\n", + "\n", + " plt.legend(loc=0,frameon=False)\n", + " plt.xlabel('Temperature')\n", + " plt.ylabel('Depth')\n", + "\n", + " plt.xlim(0,1)\n", + " plt.ylim(-1,0)\n", + " plt.title('Temperature Profiles')\n", + " if size == 1:\n", + " plt.show()\n", + " if savefigures:\n", + " plt.savefig(\"Geotherms.pdf\")" + ] + }, + { + "cell_type": "markdown", + "metadata": { + "collapsed": true + }, + "source": [ + "**Now go feel free to go back and make some changes:**\n", + "\n", + "1. Lower the maximum groundwater pressure until the perturbed geotherm is colder than the linear geotherm\n", + "2. Remove the low permeability material completely (i.e. give everything a high permeability) and check that the analaytical solution almost exact. Then explore how wide the high permeablity zone has to be for it to be effectively 1D\n", + "3. Go to where the materials are set up and make some more complicated geometries.\n", + "4. Set up a horizontal groundwater pressure gradient, make sure the thermal diffusivity is homogeneous over the domain and turn off gravity. You will need to alter the boundary conditions. If done correctly, the temperature field should not be perturbed.\n", + "5. What does the ratio of hydraulic diffusivity to storage control?" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 2", + "language": "python", + "name": "python2" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.11" + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/underworld/systems/__init__.py b/underworld/systems/__init__.py index 211f04d67..a70285372 100644 --- a/underworld/systems/__init__.py +++ b/underworld/systems/__init__.py @@ -15,6 +15,7 @@ from _advectiondiffusion import AdvectionDiffusion from _solver import Solver as _Solver from _thermal import SteadyStateHeat +from _darcyflow import SteadyStateDarcyFlow Solver=_Solver.factory diff --git a/underworld/systems/_darcyflow.py b/underworld/systems/_darcyflow.py new file mode 100644 index 000000000..c16c72685 --- /dev/null +++ b/underworld/systems/_darcyflow.py @@ -0,0 +1,262 @@ +##~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~## +## ## +## This file forms part of the Underworld geophysics modelling application. ## +## ## +## For full license and copyright information, please refer to the LICENSE.md file ## +## located at the project root, or contact the authors. ## +## ## +##~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~#~## +import underworld as uw +import underworld._stgermain as _stgermain +import sle +import libUnderworld +import numpy + +class SteadyStateDarcyFlow(_stgermain.StgCompoundComponent): + """ + This class provides functionality for a discrete representation + of the steady state darcy flow equation. + + The class uses a standard Galerkin finite element method to + construct a system of linear equations which may then be solved + using an object of the underworld.system.Solver class. + + The underlying element types are determined by the supporting + mesh used for the 'pressureField'. + + The strong form of the given boundary value problem, for :math:`f`, + :math:`q` and :math:`h` given, is + + .. math:: + \\begin{align} + q_i =& \\kappa \\, \left( -u_{,i} + S_i \right) & \\\\ + q_{i,i} =& \\: f & \\text{ in } \\Omega \\\\ + u =& \\: q & \\text{ on } \\Gamma_q \\\\ + -q_i n_i =& \\: h & \\text{ on } \\Gamma_h \\\\ + \\end{align} + + where, :math:`\\kappa` is the diffusivity, :math:`u` is the pressure, + :math:`S` is a flow body-source, for example due to gravity, + :math:`f` is a source term, :math:`q` is the Dirichlet condition, and + :math:`h` is a Neumann condition. The problem boundary, :math:`\\Gamma`, + admits the decomposition :math:`\\Gamma=\\Gamma_q\\cup\\Gamma_h` where + :math:`\\emptyset=\\Gamma_q\\cap\\Gamma_h`. The equivalent weak form is: + + .. math:: + -\\int_{\\Omega} w_{,i} \\, q_i \\, d \\Omega = \\int_{\\Omega} w \\, f \\, d\\Omega + \\int_{\\Gamma_h} w \\, h \\, d \\Gamma + + where we must find :math:`u` which satisfies the above for all :math:`w` + in some variational space. + + Parameters + ---------- + velocityField (optional): underworld.mesh.MeshVariable + Solution field for darcy flow velocity. + pressureField : underworld.mesh.MeshVariable + The solution field for pressure. + fn_diffusivity : underworld.function.Function + The function that defines the diffusivity across the domain. + fn_bodyforce (Optional) : underworld.function.Function + A function that defines the flow body-force across the domain, for example gravity. Must be a vector. + voronoi_swarm : underworld.swarm.Swarm + A swarm with just one particle within each cell should be provided. This avoids the evaluation + of the velocity on nodes and inaccuracies arising from diffusivity changes within cells. + If a swarm is provided, voronoi type numerical integration is + utilised. The provided swarm is used as the basis for the voronoi + integration. If no voronoi_swarm is provided, Gauss integration + is used. + conditions : underworld.conditions.SystemCondition + Numerical conditions to impose on the system. This should be supplied as + the condition itself, or a list object containing the conditions. + swarmVarVelocity (optional) : undeworld.swarm.SwarmVariable + If a swarm variable is provided, the velocity calculated on the swarm will be stored. + This is the most representative velocity data object, as the velocity calculation occurs + on the swarm, away from mesh nodes. + + + + Notes + ----- + Constructor must be called collectively by all processes. + + Example + ------- + Setup a basic thermal system: + + >>> linearMesh = uw.mesh.FeMesh_Cartesian( elementType='Q1/dQ0', elementRes=(4,4), minCoord=(0.,0.), maxCoord=(1.,1.) ) + >>> tField = uw.mesh.MeshVariable( linearMesh, 1 ) + >>> topNodes = linearMesh.specialSets["MaxJ_VertexSet"] + >>> bottomNodes = linearMesh.specialSets["MinJ_VertexSet"] + >>> tbcs = uw.conditions.DirichletCondition(tField, topNodes + bottomNodes) + >>> tField.data[topNodes.data] = 0.0 + >>> tField.data[bottomNodes.data] = 1.0 + >>> tSystem = uw.systems.SteadyStateDarcyFlow(pressureField=tField, fn_diffusivity=1.0, conditions=[tbcs]) + + Example with non diffusivity: + + >>> k = tField + 1.0 + >>> tSystem = uw.systems.SteadyStateDarcyFlow(pressureField=tField, fn_diffusivity=k, conditions=[tbcs]) + >>> solver = uw.systems.Solver(tSystem) + >>> solver.solve() + Traceback (most recent call last): + ... + RuntimeError: Nonlinearity detected. + Diffusivity function depends on the pressure field provided to the system. + Please set the 'nonLinearIterate' solve parameter to 'True' or 'False' to continue. + >>> solver.solve(nonLinearIterate=True) + + """ + + _objectsDict = { "_system" : "SystemLinearEquations" } + _selfObjectName = "_system" + + def __init__(self, pressureField, fn_diffusivity, fn_bodyforce=0., voronoi_swarm=None, conditions=[], velocityField = None,swarmVarVelocity = None, _removeBCs=True, **kwargs): + + if not isinstance( pressureField, uw.mesh.MeshVariable): + raise TypeError( "Provided 'pressureField' must be of 'MeshVariable' class." ) + self._pressureField = pressureField + + try: + _fn_diffusivity = uw.function.Function.convert(fn_diffusivity) + except Exception as e: + raise uw._prepend_message_to_exception(e, "Exception encountered. Note that provided 'fn_diffusivity' must be of or convertible to 'Function' class.\nEncountered exception message:\n") + + try: + _fn_bodyforce = uw.function.Function.convert(fn_bodyforce) + except Exception as e: + raise uw._prepend_message_to_exception(e, "Exception encountered. Note that provided 'fn_bodyforce' must be of or convertible to 'Function' class.\nEncountered exception message:\n") + + if voronoi_swarm and not isinstance(voronoi_swarm, uw.swarm.Swarm): + raise TypeError( "Provided 'swarm' must be of 'Swarm' class." ) + self._swarm = voronoi_swarm + if len(numpy.unique(voronoi_swarm.owningCell.data[:])) != len(voronoi_swarm.owningCell.data[:]): + import warnings + warnings.warn("It is not advised to fill any cell with more than one particle, as the Q1 shape function cannot capture material interfaces. Use at your own risk.") + + if velocityField and not isinstance( velocityField, uw.mesh.MeshVariable): + raise TypeError( "Provided 'velocityField' must be of 'MeshVariable' class." ) + self._velocityField = velocityField + + if swarmVarVelocity and not isinstance(swarmVarVelocity, uw.swarm.SwarmVariable): + raise TypeError("Provided 'swarmVarVelocity' must be of 'SwarmVariable' class.") + self._swarmVarVelocity = swarmVarVelocity + + if voronoi_swarm and pressureField.mesh.elementType=='Q2': + import warnings + warnings.warn("Voronoi integration may yield unsatisfactory results for Q2 element types. Q2 element types can also result in spurious velocity calculations.") + + if not isinstance( _removeBCs, bool): + raise TypeError( "Provided '_removeBCs' must be of type bool." ) + self._removeBCs = _removeBCs + + # error check dcs 'dirichlet conditions' and ncs 'neumann cond.' FeMesh_IndexSets + nbc = None + mesh = pressureField.mesh + + if not isinstance(conditions,(list,tuple)): + conditionslist = [] + conditionslist.append(conditions) + conditions = conditionslist + for cond in conditions: + if not isinstance( cond, uw.conditions.SystemCondition ): + raise TypeError( "Provided 'conditions' must be a list 'SystemCondition' objects." ) + # set the bcs on here + if type( cond ) == uw.conditions.DirichletCondition: + if cond.variable == pressureField: + libUnderworld.StgFEM.FeVariable_SetBC( pressureField._cself, cond._cself ) + elif type( cond ) == uw.conditions.NeumannCondition: + nbc=cond + else: + raise RuntimeError("Can't decide on input condition") + + # build the equation numbering for the temperature field discretisation + tEqNums = self._tEqNums = sle.EqNumber( pressureField, removeBCs=self._removeBCs ) + + # create solutions vector + self._solutionVector = sle.SolutionVector(pressureField, tEqNums ) + libUnderworld.StgFEM.SolutionVector_LoadCurrentFeVariableValuesOntoVector( self._solutionVector._cself ) + + # create force vectors + self._fvector = sle.AssembledVector(pressureField, tEqNums ) + + # and matrices + self._kmatrix = sle.AssembledMatrix( self._solutionVector, self._solutionVector, rhs=self._fvector ) + + + # we will use voronoi if that has been requested by the user, else use + # gauss integration. + if self._swarm: + intswarm = self._swarm._voronoi_swarm + # need to ensure voronoi is populated now, as assembly terms will call + # initial test functions which may require a valid voronoi swarm + self._swarm._voronoi_swarm.repopulate() + else: + intswarm = uw.swarm.GaussIntegrationSwarm(mesh) + + + self._kMatTerm = sle.MatrixAssemblyTerm_NA_i__NB_i__Fn( integrationSwarm=intswarm, + assembledObject=self._kmatrix, + fn=_fn_diffusivity) + + self._forceVecTerm = sle.VectorAssemblyTerm_NA_i__Fn_i( integrationSwarm=intswarm, + assembledObject=self._fvector, + fn=fn_bodyforce*fn_diffusivity) + + # search for neumann conditions + for cond in conditions: + if isinstance( cond, uw.conditions.NeumannCondition ): + #NOTE many NeumannConditions can be used but the _sufaceFluxTerm only records the last + + ### -VE flux because of Energy_SLE_Solver ### + negativeCond = uw.conditions.NeumannCondition( flux=-1.0*cond.flux, + variable=cond.variable, + nodeIndexSet=cond.indexSet ) + + self._surfaceFluxTerm = sle.VectorSurfaceAssemblyTerm_NA__Fn__ni( + assembledObject = self._fvector, + surfaceGaussPoints = 2, + nbc = negativeCond ) + super(SteadyStateDarcyFlow, self).__init__(**kwargs) + + def _setup(self): + uw.libUnderworld.StGermain.Stg_ObjectList_Append( self._cself.stiffnessMatrices, self._kmatrix._cself ) + uw.libUnderworld.StGermain.Stg_ObjectList_Append( self._cself.forceVectors, self._fvector._cself ) + uw.libUnderworld.StGermain.Stg_ObjectList_Append( self._cself.solutionVectors, self._solutionVector._cself ) + + def _add_to_stg_dict(self,componentDictionary): + # call parents method + super(SteadyStateDarcyFlow,self)._add_to_stg_dict(componentDictionary) + + def solve_velocityField(self): + fnVel = (-self._pressureField.fn_gradient + self.fn_bodyforce) * self._kMatTerm.fn + + if self._swarmVarVelocity: + self._swarmVarVelocity.data[:] = fnVel.evaluate(self._swarm) + + if self._velocityField: + velproj = uw.utils.MeshVariable_Projection(self._velocityField,fnVel,self._swarm) + velproj.solve() + + + @property + def fn_diffusivity(self): + """ + The diffusivity function. You may change this function directly via this + property. + """ + return self._kMatTerm.fn + @fn_diffusivity.setter + def fn_diffusivity(self, value): + self._kMatTerm.fn = value + + @property + def fn_bodyforce(self): + """ + The heating function. You may change this function directly via this + property. + """ + return self._forceVecTerm.fn / self._kMatTerm.fn + + @fn_bodyforce.setter + def fn_bodyforce(self, value): + self._forceVecTerm.fn = value * self._kMatTerm.fn diff --git a/underworld/systems/_energy_solver.py b/underworld/systems/_energy_solver.py index ed701a6bc..0b688664e 100644 --- a/underworld/systems/_energy_solver.py +++ b/underworld/systems/_energy_solver.py @@ -22,7 +22,7 @@ class HeatSolver(_stgermain.StgCompoundComponent): _selfObjectName = "_heatsolver" def __init__(self, heatSLE, **kwargs): - if not isinstance(heatSLE, (uw.systems.SteadyStateHeat, uw.utils.MeshVariable_Projection)): + if not isinstance(heatSLE, (uw.systems.SteadyStateHeat, uw.utils.MeshVariable_Projection)) and not isinstance(heatSLE, (uw.systems.SteadyStateDarcyFlow, uw.utils.MeshVariable_Projection)): raise TypeError("Provided system must be of 'SteadyStateHeat' class") self._heatSLE=heatSLE @@ -99,6 +99,9 @@ def solve(self, nonLinearIterate=None, nonLinearTolerance=1.0e-2, nonLinearMaxIt libUnderworld.StgFEM.SystemLinearEquations_UpdateSolutionOntoNodes(self._heatSLE._cself, None) + if isinstance(self._heatSLE, (uw.systems.SteadyStateDarcyFlow, uw.utils.MeshVariable_Projection)): + self._heatSLE.solve_velocityField() + ######################################################################## ### setup options for solve ######################################################################## diff --git a/underworld/systems/_solver.py b/underworld/systems/_solver.py index cdfd0f372..f030927fe 100644 --- a/underworld/systems/_solver.py +++ b/underworld/systems/_solver.py @@ -31,6 +31,8 @@ def factory(eqs,type="BSSCR", *args, **kwargs): return _bsscr.StokesSolver(eqs, *args, **kwargs) elif isinstance(eqs, (uw.systems.SteadyStateHeat, uw.utils.MeshVariable_Projection) ): return _energy_solver.HeatSolver(eqs, *args, **kwargs) + elif isinstance(eqs, (uw.systems.SteadyStateDarcyFlow, uw.utils.MeshVariable_Projection) ): + return _energy_solver.HeatSolver(eqs, *args, **kwargs) else: raise ValueError("Unable to create solver. Provided system not recognised.")