{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Surface Diffusion Boundary\n", "\n", "The simulation script described in this chapter is available at [STEPS_Example repository](https://github.com/CNS-OIST/STEPS_Example/blob/master/user_manual/source/surface_diffusion_boundary.ipynb).\n", "\n", "Just as it is sometimes useful to isolate some chemical species within certain volume compartments and allow others to diffuse to\n", "neighbouring compartments, as described in [Diffusion Boundary](diffusion_boundary.ipynb), it is also sometime useful to allow some chemical species to diffuse between\n", "neighbouring surface “Patches” whilst others remain isolated within one Patch. Analogously to diffusion boundaries between neighbouring compartments,\n", "“Surface diffusion boundaries” allow surface diffusion between different patches that are connected through at least one pair of neighbouring\n", "triangles in a mesh-based simulation.\n", "\n", "Since many components of this surface diffusion boundary example script have already been introduced in previous chapters and the model is based on the surface diffusion model of of [Surface Diffusion](surface_diffusion.ipynb), this chapter will be fairly brief, focusing only on the new concepts related\n", "solely to surface diffusion boundaries.\n", "\n", "Solvers [steps.solver.Tetexact](API_1/API_solver.rst#steps.API_1.solver.Tetexact) and [steps.mpi.solver.TetOpSplit](API_1/API_mpisolver.rst#steps.API_1.mpi.solver.TetOpSplit) currently support Surface Diffusion Boundaries,\n", "but this chapter will only show an example with the Tetexact solver. Since the solvers share an API, use is functionally equivalent in TetOpSplit.\n", "\n", "\n", "## Modelling solution\n", "\n", "### Organisation of code\n", "\n", "As for previous models we will create a Python script to run the surface diffusion model.\n", "\n", "As usual, at first we import STEPS modules and other modules `pylab` and `math`:\n" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "import steps.model as smodel\n", "import steps.geom as stetmesh\n", "import steps.utilities.meshio as smeshio\n", "import steps.rng as srng\n", "import steps.solver as solvmod\n", "import pylab\n", "import math" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We set some simulation constants:\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Number of iterations; plotting dt; sim endtime:\n", "NITER = 10\n", "\n", "# The data collection time increment (s)\n", "DT = 1.0\n", "\n", "# The simulation endtime (s)\n", "INT = 21.0\n", "\n", "# Number of molecules injected in centre\n", "NINJECT = 1000\n", "\n", "# The diffusion constant for our diffusing species (m^2/s)\n", "DCST = 0.08e-12" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Model specification\n", "\n", "We create the biochemical model, equivalent to the surface diffusion model in [Surface Diffusion](surface_diffusion.ipynb) where we create\n", "one species `X` and one surface diffusion rule:\n" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "def gen_model():\n", " mdl = smodel.Model()\n", " X = smodel.Spec('X', mdl)\n", " ssys = smodel.Surfsys('ssys', mdl)\n", " diff_X = smodel.Diff('diffX', ssys, X, DCST)\n", " return mdl" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Geometry specification\n", "\n", "The geometry for the simulation is the same flat disk-shaped tetrahedral mesh of radius 10 microns as in\n", "the [Surface Diffusion](surface_diffusion.ipynb) example. This time, however, the circular surface will be separated into two Patches on the x=0 axis\n", "which will be connected by a Surface Diffusion Boundary, as we will see later.\n", "\n", "![The mesh used for the surface diffusion boundary simulation](images/coin_sdb.png)\n", "\n", "This is the disk-shaped mesh of radius 10 microns used for the simulation in this chapter. The region in red is ’Patch A’ and blue is ‘Patch B’. We will create a Surface Diffusion Boundary to connect these two Patches. \n", "\n", "The first step is to import the tetrahedral mesh." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "mesh = smeshio.loadMesh('meshes/coin_10r_1h_13861')[0]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Then we create a compartment comprising all mesh tetrahedrons:\n" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "ntets = mesh.countTets()\n", "comp = stetmesh.TmComp('cyto', mesh, range(ntets))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We go on to creating the surface [steps.geom.TmPatch](API_1/API_geom.rst#steps.API_1.geom.TmPatch) objects for this mesh-based simulation,\n", "but, differently from the [Surface Diffusion](surface_diffusion.ipynb) example, we separate the surface into two Patches. The centre of the\n", "mesh is at the origin (x=0, y=0, z=0) and so to split evenly in this simple example one Patch is comprised of triangles with +ve x barycentre\n", "and the other with -ve x barycentres.\n", "\n", "In order to create a Surface Diffusion Boundary we need to find information about the triangle ‘bars’ here. In STEPS, the\n", "edges created by joining two vertices of any triangle are termed ‘bars’, and we can use\n", "function [steps.geom.Tetmesh.getTriBars](API_1/API_geom.rst#steps.API_1.geom.Tetmesh.getTriBars) to get that information. In fact in this example we already\n", "have the vertex information so the call to [steps.geom.Tetmesh.getTriBars](API_1/API_geom.rst#steps.API_1.geom.Tetmesh.getTriBars) is not strictly necessary, but we demonstrate its use here:\n" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "alltris = mesh.getSurfTris()\n", "\n", "# Sort patch triangles as those of positive z: A +ve x, B -ve x\n", "patchA_tris = []\n", "patchB_tris = []\n", "patchA_bars = set()\n", "patchB_bars = set()\n", "\n", "for t in alltris:\n", " vert0, vert1, vert2 = mesh.getTri(t)\n", " if (mesh.getVertex(vert0)[2] > 0.0 \\\n", " and mesh.getVertex(vert1)[2] > 0.0 \\\n", " and mesh.getVertex(vert2)[2] > 0.0):\n", " if mesh.getTriBarycenter(t)[0] > 0.0:\n", " patchA_tris.append(t)\n", " bar = mesh.getTriBars(t)\n", " patchA_bars.add(bar[0])\n", " patchA_bars.add(bar[1])\n", " patchA_bars.add(bar[2])\n", " else:\n", " patchB_tris.append(t)\n", " bar = mesh.getTriBars(t)\n", " patchB_bars.add(bar[0])\n", " patchB_bars.add(bar[1])\n", " patchB_bars.add(bar[2])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We create the two [steps.geom.TmPatch](API_1/API_geom.rst#steps.API_1.geom.TmPatch) objects. We call the Patch with +ve x (red in the figure above) `'PatchA'`\n", "and the Patch with -ve x (blue in in the figure above) `'PatchB'`. Both share the same inner compartment we created earlier:\n" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Create the patch\n", "patchA = stetmesh.TmPatch('patchA', mesh, patchA_tris, icomp=comp)\n", "patchA.addSurfsys('ssys')\n", "patchB = stetmesh.TmPatch('patchB', mesh, patchB_tris, icomp=comp)\n", "patchB.addSurfsys('ssys')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now we can create the [steps.geom.SDiffBoundary](API_1/API_geom.rst#steps.API_1.geom.SDiffBoundary) object. Analogously to the Diffusion Boundary between Compartments\n", "which is made up of connecting triangles between those compartments, the Surface Diffusion Boundary is comprised\n", "of a collection of ‘bars’ that connect two distinct Patches. The first thing, then, is to find that set of bars as the\n", "intersection between all bars from `PatchA` and `PatchB`:\n" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Find the set of bars that connect the two patches as the intersecting bars of PatchA and PatchB\n", "barsDB = patchA_bars.intersection(patchB_bars)\n", "barsDB = list(barsDB)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "So the list `barsDB` contains the indices of the common bars to both patchA and patchB, which are the bars\n", "connecting the two Patches and will form the Surface Diffusion Boundary.\n", "\n", "One more important point about Surface Diffusion Boundary creation is that the constructor requires a sequence containing\n", "references to the two [steps.geom.TmPatch](API_1/API_geom.rst#steps.API_1.geom.TmPatch) objects that it connects, in this case `patchA` and `patchB`. The reason\n", "for this is that any given bar within the Surface Diffusion Boundary can be connected to any number of triangles (not just 2) which\n", "can belong to more than 2 Patches, and providing this information to the Surface Diffusion Boundary constructor avoids\n", "ambiguity. In practice, many bars set up in such a way will only be connected to 2 triangles that are contained within\n", "surface Patches but being explicit here is in the setup is good practice and aids STEPS in setting up the model correctly.\n", "\n", "So we can go ahead and create the Surface Diffusion Boundary. Arguments to the constructor are, in order: a string identifier, a\n", "reference to the parent [steps.geom.Tetmesh](API_1/API_geom.rst#steps.API_1.geom.Tetmesh) parent object, a reference to the sequence of bars that make up the Surface\n", "Diffusion Boundary, and a sequence of length 2 containing references to the 2 connected Patch objects:\n" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Create the surface diffusion boundary\n", "diffb = stetmesh.SDiffBoundary('sdiffb', mesh, barsDB, [patchA, patchB])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The next part of the code follows similarly to in [Surface Diffusion](surface_diffusion.ipynb) in recording the triangle radii and areas,\n", "with the difference that we now separate into patchA and patchB. The triangle radii in patchB will be given negative sign\n", "to differentiate from those in patchA:\n" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Find the central tri\n", "ctetidx = mesh.findTetByPoint([0.0, 0.0, 0.5e-6])\n", "ctet_trineighbs = mesh.getTetTriNeighb(ctetidx)\n", "ctri_idx=-1\n", "for t in ctet_trineighbs:\n", " if t in patchA_tris+patchB_tris:\n", " ctri_idx = t \n", "cbaryc = mesh.getTriBarycenter(ctri_idx)\n", "\n", "# Record the tri radii from centre and areas for patchA and patchB\n", "trirads_A = pylab.zeros(len(patchA_tris))\n", "trirads_B = pylab.zeros(len(patchB_tris))\n", "triareas_A = pylab.zeros(len(patchA_tris))\n", "triareas_B = pylab.zeros(len(patchB_tris))\n", "\n", "for i in range(len(patchA_tris)):\n", " baryc = mesh.getTriBarycenter(patchA_tris[i])\n", " r2 = math.pow((baryc[0]-cbaryc[0]),2) + \\\n", " math.pow((baryc[1]-cbaryc[1]),2) + \\\n", " math.pow((baryc[2]-cbaryc[2]),2)\n", " r = math.sqrt(r2)\n", " # Convert to microns\n", " trirads_A[i] = r*1.0e6\n", " triareas_A[i] = mesh.getTriArea(patchA_tris[i])*1.0e12\n", "\n", "for i in range(len(patchB_tris)):\n", " baryc = mesh.getTriBarycenter(patchB_tris[i])\n", " r2 = math.pow((baryc[0]-cbaryc[0]),2) + \\\n", " math.pow((baryc[1]-cbaryc[1]),2) + \\\n", " math.pow((baryc[2]-cbaryc[2]),2)\n", " r = math.sqrt(r2)\n", " # Convert to microns\n", " trirads_B[i] = -r*1.0e6\n", " triareas_B[i] = mesh.getTriArea(patchB_tris[i])*1.0e12" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Simulation with ``Tetexact``\n", "\n", "We're now ready to run the simulation and collect data. As usual we require a reference to a [steps.model.Model](API_1/API_model.rst#steps.API_1.model.Model)\n", "object, which we retrieve by a call to function ``gen_model``, and a [steps.geom.Tetmesh](API_1/API_geom.rst#steps.API_1.geom.Tetmesh) objects, which we have already\n", "created and store in reference `mesh`. Finally we need a random number generator and we can create\n", "our [steps.solver.Tetexact](API_1/API_solver.rst#steps.API_1.solver.Tetexact) solver object:\n" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Create the biochemical model\n", "model = gen_model()\n", "\n", "# Create rnadom number generator object\n", "rng = srng.create('mt19937', 512)\n", "rng.initialize(234)\n", "\n", "# Create solver object\n", "sim = solvmod.Tetexact(model, mesh, rng)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "We, similar to previous chapters, create arrays to help run the simulation and to record data, separated into patchA and patchB:\n" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "# Create the simulation data structures\n", "tpnts = pylab.arange(0.0, INT, DT)\n", "ntpnts = tpnts.shape[0]\n", "res_A = pylab.zeros((NITER, ntpnts, len(patchA_tris)))\n", "res_B = pylab.zeros((NITER, ntpnts, len(patchB_tris)))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And we are ready to run the simulation. The default behaviour of the Surface Diffusion Boundary is to be inactive, that is to\n", "block diffusion of molecules between patchA and patchB in this example. To activate diffusion between patchA and patchB\n", "we need to call solver function [steps.solver.Tetexact.setSDiffBoundaryDiffusionActive](API_1/API_solver.rst#steps.API_1.solver.Tetexact.setSDiffBoundaryDiffusionActive). Use of this function is to\n", "identify the Surface Diffusion Boundary and Species by string (in this example ’sdiffb’ and ‘X’ respectively) and to activate\n", "with `True` or deactivate with `False`. However, for both Diffusion Boundaries between Compartments and Surface Diffusion\n", "Boundaries between Patches, diffusion across a boundary isn’t all or none. Function [steps.solver.Tetexact.setSDiffBoundaryDcst](API_1/API_solver.rst#steps.API_1.solver.Tetexact.setSDiffBoundaryDcst)\n", "allows control of diffusion rate across the boundary (where default is as the coefficient specified within the compartment or patch in model setup).\n", "As well as the required 3 arguments to this function specifying the Surface Diffusion Boundary and Species by string and specifying the diffusion\n", "coefficient, a final optional argument specifies the direction of diffusion, specified as a string reference to a Patch. E.g. if we call this function with argument string `patchB` then we set the diffusion coefficient of the specified species across the boundary towards patchB. Otherwise the diffusion coefficient would be set in both directions across the Surface Diffusion Boundary to the value specified.\n", "\n", "We inject all molecules in the central triangle, which happens to be just inside patchA. Then we activate the Surface Diffusion Boundary with\n", "function call [steps.solver.Tetexact.setSDiffBoundaryDiffusionActive](API_1/API_solver.rst#steps.API_1.solver.Tetexact.setSDiffBoundaryDiffusionActive) and slow down diffusion from patchA towards patchB by\n", "calling [steps.solver.Tetexact.setSDiffBoundaryDcst](API_1/API_solver.rst#steps.API_1.solver.Tetexact.setSDiffBoundaryDcst) with the slow diffusion rate of 0.008e-12 (10% of the default diffusion rate). Finally, we run\n", "the simulation `NITER` times and record data:\n" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "('Running iteration', 0)\n", "('Running iteration', 1)\n", "('Running iteration', 2)\n", "('Running iteration', 3)\n", "('Running iteration', 4)\n", "('Running iteration', 5)\n", "('Running iteration', 6)\n", "('Running iteration', 7)\n", "('Running iteration', 8)\n", "('Running iteration', 9)\n" ] } ], "source": [ "# Run NITER number of iterations:\n", "for j in range(NITER):\n", " print(\"Running iteration\", j)\n", " sim.reset()\n", " sim.setTriCount(ctri_idx, 'X', NINJECT)\n", " sim.setSDiffBoundaryDiffusionActive('sdiffb', 'X', True)\n", " sim.setSDiffBoundaryDcst('sdiffb', 'X', 0.008e-12 , 'patchB')\n", "\n", " for i in range(ntpnts):\n", " sim.run(tpnts[i])\n", " for k in range(len(patchA_tris)):\n", " res_A[j, i, k] = sim.getTriCount(patchA_tris[k], 'X')/ \\\n", " triareas_A[k]\n", " for k in range(len(patchB_tris)):\n", " res_B[j, i, k] = sim.getTriCount(patchB_tris[k], 'X')/ \\\n", " triareas_B[k]" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Take the mean of the results over the 10 iterations:\n" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "res_A_mean = pylab.mean(res_A, axis = 0)\n", "res_B_mean = pylab.mean(res_B, axis = 0)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Plotting simulation output\n", "\n", "Finally we plot the data, plotting data for patchA as positive radii and for patchB as negative radii. This way it is easy to visualise\n", "the separate patches and the effect of the diffusion boundary:\n" ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": true, "jupyter": { "outputs_hidden": true } }, "outputs": [], "source": [ "def plotres(tidx):\n", " if (tidx >= INT/DT):\n", " print(\"Time index is out of range.\")\n", " return\n", "\n", " pylab.plot(trirads_A, res_A_mean[tidx], 'bo', label='patchA')\n", " pylab.plot(trirads_B, res_B_mean[tidx], 'ro', label='patchB')\n", "\n", " pylab.xlabel('Radial distance ($\\mu$m)')\n", " pylab.ylabel('Concentration (/$\\mu$m$^2$)')\n", " t = tpnts[tidx]\n", " pylab.xlim(-10,10)\n", " pylab.ylim(0)\n", " pylab.legend()\n", " pylab.show()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "And a call to the function with the last ‘timepoint’ of 20, equivalent to 20seconds:\n" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "data": { "image/png": "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\n9t/N7Dtm9rCZfcnMTovZj+dDg1V6bJvZCfnXqyfy7wHDzW9ldzOzc8zsATN7NP8+vbnEPleb2Y8L\nXqt+qxVt7XaVXmMs+KP88+FhM/u5VrSzW5nZ+QWP8b1m9oKZ/XrRPjwXUmBmd5jZD81sf8G2NWb2\nVTP7bv789Jjbbszv810z21jV/XXqkD8zu0DSgqRPS/oNd5/Mb79Q0l2SLpf005Luk/Qz7j5fdPs/\nl/SX7v4FM/uUpG+7++3N/B26lZn9nqQfu/ttJa6bkjTi7qxDkgIz+6ikw+7+P8rs0y/pXyS9WWGh\n7N2S3uvujzalkT3AzH5R0tfyRXU+IUnu/uES+02J50PDVPPYNrNNkl7j7jeZ2XWS3unu72lJg7uU\nmZ0l6Sx3/5aZnSJpj6R3FP0frlZ4735bi5rZEyq9xuS/dLtV0npJV0ja4u5XNK+FvSP/+vSUwlqq\n0wXbrxbPhYYzs/8g6bCkP3P3i/Lb/pukg+7+8fwXbqcXvzeb2RpJk5JGJLnC69dr3f35cvfXsT1U\n7v6Yuz9e4qq3S/qCu/+bu39P0hMK4eolZmaS3ihpZ37TNknvSLO9vSL/t323QqhFe7pc0hPu/q/u\nflTSFxSeN2gQd/87dz+ev/hNhfXzkL5qHttvV3jNl8J7wLr86xYaxN2fcfdv5X8+JOkxSa9obasQ\n4+0KHzjd3b8p6bR8IEbjrZP0vwrDFNLj7v8o6WDR5sLX/7jP/m+R9FV3P5gPUV+VdE2l++vYQFXG\nKyQ9WXD5gJa/kA9K+lHBB55S+6A2/17SD9z9uzHXu6S/M7M9ZjbaxHb1klvyQzfuiOnOruY5gsa5\nUdLfxFzH86Gxqnlsv7RP/j3gxwrvCUhBfkjlz0p6qMTVP29m3zazvzGz/62pDesdlV5jeD9onusU\n/2Uzz4XmONPdn8n//H1JZ5bYp6bnRFuXTTez+yS9vMRVY+5+d7Pb0+uq/H+8V+V7p65y96fM7Kck\nfdXMvpP/FgFVKvd/kHS7pI8pvIl+TNLvKXygR4NV83wwszFJxyXlYg7D8wFdy8xOlvRFSb/u7i8U\nXf0tSRl3P5wfdvZXks5rdht7AK8xbcDCPP1flvSbJa7mudAC7u5m1rB5T20dqNz9TTXc7ClJ5xRc\nPju/rdCsQrf2ivw3lKX2QZFK/w8zWyHpP0p6bZljPJU//6GZfUlhiA4v7glU+7wwsz+R9OUSV1Xz\n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\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "pylab.figure(figsize=(14,7))\n", "plotres(20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "This plot shows a surface diffusion where the low rate of diffusion from patchA towards patchB can clearly\n", "be seen by the lower concentration in patchB." ] } ], "metadata": { "kernelspec": { "display_name": "Python 3", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.8.10" } }, "nbformat": 4, "nbformat_minor": 4 }