{
  "cells": [
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "%matplotlib inline"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "\n\n# Tutorial 03: Boundary conditions\n\nThe particle systems are defined in a rectangular box whose dimensions are specified by the attribute :attr:`L <sisyphe.Particles.particles.L>`. \n\nThe boundary conditions are specified by the attribute :attr:`bc <sisyphe.Particles.particles.bc>` which can be one of the following. \n\n* A list of size $d$ containing for each dimension either 0 (periodic) or 1 (wall with reflecting boundary conditions).\n\n* The string ``\"open\"`` : no boundary conditions.\n\n* The string ``\"periodic\"`` : periodic boundary conditions.\n\n* The string ``\"spherical\"`` : reflecting boundary conditions on the sphere of diameter $L$ enclosed in the square domain $[0,L]^d$. \n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "For instance, let us simulate the Vicsek model in an elongated rectangular domain $[0,L_x]\\times[0,L_y]$ with periodic boundary conditions in the $x$-dimension and reflecting boundary conditions in the $y$-dimension. \n\nFirst, some standard imports...\n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "import time \nimport torch\nfrom sisyphe.models import Vicsek\nfrom sisyphe.display import display_kinetic_particles\n\nuse_cuda = torch.cuda.is_available()\ndtype = torch.cuda.FloatTensor if use_cuda else torch.FloatTensor"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The parameters of the model \n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "N = 100000\n\nR = .01\nc = .1\nnu = 3.\nsigma = 1.\n\ndt = .01\n\nvariant = {\"name\" : \"max_kappa\", \"parameters\" : {\"kappa_max\" : 10.}}"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The spatial domain, the boundary conditions and the initial conditions... \n\n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "Lx = 3.\nLy = 1./3.\nL = [Lx, Ly]\nbc = [0,1]\n\npos = torch.rand((N,2)).type(dtype)\npos[:,0] = L[0]*pos[:,0]\npos[:,1] = L[1]*pos[:,1]\nvel = torch.randn(N,2).type(dtype)\nvel = vel/torch.norm(vel,dim=1).reshape((N,1))\n\nsimu = Vicsek(\n    pos = pos.detach().clone(),\n    vel = vel.detach().clone(), \n    v = c, \n    sigma = sigma, \n    nu = nu, \n    interaction_radius = R,\n    box_size = L,\n    boundary_conditions=bc,\n    dt = dt,\n    variant = variant,\n    block_sparse_reduction = True,\n    number_of_cells = 100**2)"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Finally run the simulation over 300 units of time.... \n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "# sphinx_gallery_thumbnail_number = 15\n\nframes = [0., 2., 5., 10., 30., 42., 71., 100, 123, 141, 182, 203, 256, 272, 300]\n\ns = time.time()\nit, op = display_kinetic_particles(simu, frames, order=True, figsize=(8,3))\ne = time.time()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "Print the total simulation time and the average time per iteration. \n\n"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": null,
      "metadata": {
        "collapsed": false
      },
      "outputs": [],
      "source": [
        "print('Total time: '+str(e-s)+' seconds')\nprint('Average time per iteration: '+str((e-s)/simu.iteration)+' seconds')"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "The simulation produces small clusters moving from left to right or from right to left. Each \"step\" in the order parameter corresponds to a collision between two clusters moving in opposite directions. \n\n"
      ]
    }
  ],
  "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.5"
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}