Skip to content
Snippets Groups Projects
MetaVoxel_Tutorial.ipynb 17.8 KiB
Newer Older
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# MetaVoxel Tutorial"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Amira Abdel-Rahman\n",
    "# (c) Massachusetts Institute of Technology 2020\n",
    "\n",
    "# tested using julia 1.2.0 and windows Nvidia geforce gtx 1070 Ti"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Import Julia Libraries"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [],
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "source": [
    "using LinearAlgebra\n",
    "# using Plots\n",
    "import JSON\n",
    "using StaticArrays, BenchmarkTools\n",
    "using Base.Threads\n",
    "using CUDAnative\n",
    "using CuArrays,CUDAdrv \n",
    "import Base: +, * , -, ^"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "axialStrain (generic function with 1 method)"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "include(\"./julia/include/vector.jl\") #utils for vectors and quaternions\n",
    "include(\"./julia/include/material.jl\") #utils for node and edge material\n",
    "include(\"./julia/include/export.jl\") #export simulation data to json\n",
    "include(\"./julia/include/run.jl\") #turn setup to cuda arrays and run simulation\n",
    "include(\"./julia/include/updateEdges.jl\") #edges properties update\n",
    "include(\"./julia/include/externalForces.jl\") #external forces applied to the system\n",
    "include(\"./julia/include/forces.jl\") #force integration\n",
    "include(\"./julia/include/updateNodes.jl\") #nodes properties update"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 1. Voxel Design"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "\"tutorial\""
      ]
     },
     "execution_count": 34,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# set name for simulation\n",
    "name= \"tutorial\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.a. Import lines from Rhino (.3dm)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "rhino=true\n",
    "\n",
    "setup = Dict()\n",
    "\n",
    "setup[\"rhino\"]=rhino\n",
    "setup[\"rhinoFileName\"]=\"./julia/examples/trial.3dm\";\n",
    "setup[\"layerIndex\"]=\"1\"; #layer index to import, only lines from these layer will get imported\n",
    "setup[\"voxelList\"]=false\n",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
    "\n",
    "# make sure to divide curves into smaller lines, it will only add nodes at the start and end of each line/curve\n",
    "\n",
    "voxelSize=75 #in case you want to array the base rhino curve, what is the size of the voxel\n",
    "latticeSizeX=2 # if you don't want to copy/array make this 1\n",
    "latticeSizeY=2 # if you don't want to copy/array make this 1\n",
    "latticeSizeZ=2 # if you don't want to copy/array make this 1\n",
    "\n",
    "setup[\"latticeSizeX\"]=latticeSizeX\n",
    "setup[\"latticeSizeY\"]=latticeSizeY\n",
    "setup[\"latticeSizeZ\"]=latticeSizeZ\n",
    "\n",
    "gridSize=10 #lattice size\n",
    "setup[\"gridSize\"]=gridSize\n",
    "\n",
    "#scaling params\n",
    "setup[\"voxelSize\"]=voxelSize; #voxel size\n",
    "setup[\"scale\"]=1e4; #scale for visualization\n",
    "setup[\"hierarchical\"]=false; #hierachical simualtion\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.b Draw Lattice"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "rhino=false\n",
    "\n",
    "voxelSize=0.001\n",
    "latticeSizeX=7\n",
    "latticeSizeY=2\n",
    "latticeSizeZ=2\n",
    "\n",
    "gridSize=10\n",
    "\n",
    "setup = Dict()\n",
    "setup[\"gridSize\"]=gridSize\n",
    "\n",
    "setup[\"rhino\"]=false\n",
    "setup[\"voxelList\"]=false\n",
    "\n",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
    "\n",
    "setup[\"latticeSizeX\"]=latticeSizeX\n",
    "setup[\"latticeSizeY\"]=latticeSizeY\n",
    "setup[\"latticeSizeZ\"]=latticeSizeZ\n",
    "\n",
    "#scaling params\n",
    "setup[\"voxelSize\"]=voxelSize; #voxel size\n",
    "setup[\"scale\"]=1e4; #scale for visualization\n",
    "setup[\"hierarchical\"]=true; #hierachical simualtion \n",
    "# if setup[\"hierarchical\"] is true it will assume each voxel is one node, \n",
    "# else it will assume each voxel is a detailed cuboct"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.c. Fill mesh with voxels (wip)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "# rhino=false\n",
    "# rhinoFileName= \"./trial.stl\"\n",
    "# voxelSize=5.0"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 1.c. Draw from voxel list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "setup[\"useVoxelList\"]=false\n"
   ]
  },
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 2. Boundary Conditions"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.a. Global Settings"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "#simulation params\n",
    "setup[\"numTimeSteps\"]=5000; #num of saved timesteps for simulation\n",
    "\n",
    "setup[\"poisson\"]=false; # account for poisson ration (only for hierarchical)\n",
    "setup[\"linear\"]=true; # linear vs non-linear\n",
    "setup[\"thermal\"]=true; #if there is change in temperature\n",
    "setup[\"globalDamping\"]=0.15; # (usually from 0.1 to 0.4)\n",
    "\n",
    "\n",
    "#visualization params\n",
    "setup[\"maxNumFiles\"]=200; #num of saved timesteps for visualization, make sure it's bigger than numTimeSteps\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.b. Materials"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "#default material\n",
    "material1= Dict()\n",
    "material1[\"area\"]=voxelSize*voxelSize\n",
    "material1[\"density\"]=1e3\n",
    "material1[\"stiffness\"]=1e6\n",
    "material1[\"poissonRatio\"]=0.0\n",
    "material1[\"cTE\"]=0.0 #coefficient of thermal expansion\n",
    "\n",
    "#large bounding box for default material\n",
    "boundingBoxMaterial1=Dict()\n",
    "boundingBoxMaterial1[\"min\"]=Dict()\n",
    "boundingBoxMaterial1[\"max\"]=Dict()\n",
    "\n",
    "boundingBoxMaterial1[\"min\"][\"x\"]=-voxelSize*gridSize;\n",
    "boundingBoxMaterial1[\"min\"][\"y\"]=-voxelSize*gridSize;\n",
    "boundingBoxMaterial1[\"min\"][\"z\"]=-voxelSize*gridSize;\n",
    "\n",
    "boundingBoxMaterial1[\"max\"][\"x\"]= voxelSize*gridSize;\n",
    "boundingBoxMaterial1[\"max\"][\"y\"]= voxelSize*gridSize;\n",
    "boundingBoxMaterial1[\"max\"][\"z\"]= voxelSize*gridSize;"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "#second material\n",
    "material2= Dict()\n",
    "material2[\"area\"]=voxelSize*voxelSize\n",
    "material2[\"density\"]=1e3\n",
    "material2[\"stiffness\"]=1e6\n",
    "material2[\"poissonRatio\"]=0.0\n",
    "material2[\"cTE\"]=0.1 #coefficient of thermal expansion\n",
    "\n",
    "#bounding box material 2\n",
    "boundingBoxMaterial2=Dict()\n",
    "boundingBoxMaterial2[\"min\"]=Dict()\n",
    "boundingBoxMaterial2[\"max\"]=Dict()\n",
    "\n",
    "\n",
    "boundingBoxMaterial2[\"min\"][\"x\"]=0;\n",
    "boundingBoxMaterial2[\"min\"][\"y\"]=voxelSize;\n",
    "boundingBoxMaterial2[\"min\"][\"z\"]=0;\n",
    "\n",
    "boundingBoxMaterial2[\"max\"][\"x\"]= voxelSize*(latticeSizeX);\n",
    "boundingBoxMaterial2[\"max\"][\"y\"]= voxelSize*(latticeSizeY);\n",
    "boundingBoxMaterial2[\"max\"][\"z\"]= voxelSize*(latticeSizeZ);"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "setup[\"materials\"]=[\n",
    "    [boundingBoxMaterial1,material1],\n",
    "    [boundingBoxMaterial2,material2]\n",
    "];"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.c. Supports"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [],
   "source": [
    "#x,y,z,rx,ry,rz (default is pinned joing i.e [false,false,false,true,true,true])\n",
    "dof=[true,true,true,true,true,true]\n",
    "\n",
    "boundingBoxSupport1=Dict()\n",
    "boundingBoxSupport1[\"min\"]=Dict()\n",
    "boundingBoxSupport1[\"max\"]=Dict()\n",
    "\n",
    "\n",
    "boundingBoxSupport1[\"min\"][\"x\"]= 0;\n",
    "boundingBoxSupport1[\"min\"][\"y\"]= 0;\n",
    "boundingBoxSupport1[\"min\"][\"z\"]= 0;\n",
    "\n",
    "boundingBoxSupport1[\"max\"][\"x\"]= voxelSize;\n",
    "boundingBoxSupport1[\"max\"][\"y\"]= voxelSize*(latticeSizeY);\n",
    "boundingBoxSupport1[\"max\"][\"z\"]= voxelSize*(latticeSizeZ);\n",
    "\n",
    "setup[\"supports\"]=[\n",
    "        [boundingBoxSupport1,dof]\n",
    "    ];"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 2.d. Loads"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.d.1 Static Loads"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "load1=Dict()\n",
    "load1[\"x\"]=0.0\n",
    "load1[\"y\"]=0.0\n",
    "load1[\"z\"]=0.0\n",
    "\n",
    "boundingBoxLoad1=Dict()\n",
    "boundingBoxLoad1[\"min\"]=Dict()\n",
    "boundingBoxLoad1[\"max\"]=Dict()\n",
    "\n",
    "boundingBoxLoad1[\"min\"][\"x\"]=voxelSize*(latticeSizeX-1);\n",
    "boundingBoxLoad1[\"min\"][\"y\"]=0;\n",
    "boundingBoxLoad1[\"min\"][\"z\"]=0;\n",
    "\n",
    "boundingBoxLoad1[\"max\"][\"x\"]=voxelSize*(latticeSizeX);\n",
    "boundingBoxLoad1[\"max\"][\"y\"]=voxelSize*(latticeSizeY);\n",
    "boundingBoxLoad1[\"max\"][\"z\"]=voxelSize*(latticeSizeZ);\n",
    "\n",
    "\n",
    "setup[\"loads\"]=[\n",
    "        [boundingBoxLoad1,load1]\n",
    "    ];"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.d.2 Fixed Displacements"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "setup[\"fixedDisplacements\"]=[];"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "#### 2.d.3 Dynamic Loads"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 73,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "updateTemperature (generic function with 1 method)"
      ]
     },
     "execution_count": 73,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function floorEnabled()\n",
    "    return false\n",
    "end\n",
    "\n",
    "function gravityEnabled()\n",
    "    return false\n",
    "end\n",
    "\n",
    "function externalDisplacement(currentTimeStep,N_position,N_fixedDisplacement)\n",
    "    return N_fixedDisplacement\n",
    "end\n",
    "\n",
    "function externalForce(currentTimeStep,N_position,N_force)\n",
    "    if currentTimeStep>1000\n",
    "        return Vector3(0,0,0)\n",
    "    else\n",
    "        return N_force\n",
    "    end\n",
    "end\n",
    "\n",
    "# if no temperature:\n",
    "# function updateTemperature(currentRestLength,currentTimeStep,mat)\n",
    "#     return currentRestLength\n",
    "# end\n",
    "\n",
    "function updateTemperature(currentRestLength,currentTimeStep,mat)\n",
    "    if currentTimeStep<1000\n",
    "        temp=-5.0*currentTimeStep/1000\n",
    "        currentRestLength=0.5*mat.L*(2.0+temp*mat.cTE)\n",
    "    elseif currentTimeStep==2500\n",
    "        temp=0\n",
    "        currentRestLength=0.5*mat.L*(2.0+temp*mat.cTE)\n",
    "    end\n",
    "    return currentRestLength\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 3. Export setup to json"
   ]
  },
  {
   "cell_type": "code",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "execution_count": 234,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "axialStrain (generic function with 1 method)"
      ]
     },
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "execution_count": 234,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# alternativly you can get a saved setup from an external julia file\n",
    "# include(\"./julia/examples/thermalTest.jl\") #template for multimaterial hierarchical voxels with different thermal coefficient of thermal expansion \n",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
    "# include(\"./julia/examples/poissonTest.jl\") #template for hierarchical voxels with global poisson ratio\n",
    "# include(\"./julia/examples/latticeTest.jl\") #template for lattice voxel (small scale)\n",
    "# include(\"./julia/examples/latticeTest2.jl\") #template for lattice voxel (big scale with real params)\n",
    "# include(\"./julia/examples/rhinoTest.jl\") #template for importing geometry from rhino\n",
    "# include(\"./julia/examples/rhinoTestChiral.jl\") #template for importing chiral array\n",
    "include(\"./julia/examples/rover.jl\") #template for importing chiral array\n",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
    "\n",
    "\n",
    "## rerun these just for sanity check for dynamic loads\n",
    "include(\"./julia/include/run.jl\") #turn setup to cuda arrays and run simulation\n",
    "include(\"./julia/include/updateEdges.jl\") #edges properties update\n",
    "include(\"./julia/include/forces.jl\") #force integration\n",
    "include(\"./julia/include/updateNodes.jl\") #nodes properties update"
   ]
  },
  {
   "cell_type": "code",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "execution_count": 235,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "2097"
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
      ]
     },
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "execution_count": 235,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#export prev. settings to json\n",
    "fileName=\"./json/$(name)Init.json\"\n",
    "setup1=Dict()\n",
    "setup1[\"setup\"]=setup\n",
    "stringdata = JSON.json(setup1)\n",
    "open(fileName, \"w\") do f\n",
    "        write(f, stringdata)\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "execution_count": 236,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Loaded rhino3dm.\n",
      "Success!\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "Process(`\u001b[4mnode\u001b[24m \u001b[4mapp1.js\u001b[24m \u001b[4mtutorial\u001b[24m`, ProcessExited(0))"
      ]
     },
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "execution_count": 236,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "#run node.js to draw the gerometry using rhino3dm\n",
    "mycommand = `node app1.js $(name)`\n",
    "run(mycommand)\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 4. Run Simulation"
   ]
  },
  {
   "cell_type": "code",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "execution_count": 237,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "dt: 5.032921456503956e-6\n",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
      "first timestep took 29.999862 seconds\n",
      "ran 17 nodes and 16 edges for 10000 time steps took 8.470833901 seconds\n"
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     ]
    }
   ],
   "source": [
    "folderPath=\"./json/tutorial/\" # make sure this folder exists\n",
    "setupSim=getSetup(name);\n",
    "runMetavoxelGPULive!(setupSim,folderPath)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 5. Visualize \n",
    "(only need to run it once to open the server then press stop, the server will keep running and other changes will update automatically.. will change later)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 49,
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Server listening on port 8080\n",
      "Open http://localhost:8080/demos/indexTutorial.html in your browser\n"
     ]
    },
    {
     "ename": "InterruptException",
     "evalue": "InterruptException:",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     "output_type": "error",
     "traceback": [
      "InterruptException:",
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
      "",
      "Stacktrace:",
      " [1] try_yieldto(::typeof(Base.ensure_rescheduled), ::Base.RefValue{Task}) at .\\task.jl:517",
      " [2] wait() at .\\task.jl:592",
      " [3] wait(::Base.GenericCondition{Base.AlwaysLockedST}) at .\\condition.jl:104",
      " [4] stream_wait(::Base.Process, ::Base.GenericCondition{Base.AlwaysLockedST}) at .\\stream.jl:47",
      " [5] wait at .\\process.jl:956 [inlined]",
      " [6] success at .\\process.jl:771 [inlined]",
      " [7] #run#536(::Bool, ::typeof(run), ::Cmd) at .\\process.jl:728",
      " [8] run(::Cmd) at .\\process.jl:726",
      " [9] top-level scope at In[49]:3"
Amira Abdel-Rahman's avatar
Amira Abdel-Rahman committed
     ]
    }
   ],
   "source": [
    "#run node.js to serve the indexTutorial.html for visualizarion\n",
    "mycommand = `node serve.js $(name)`\n",
    "run(mycommand)\n",
    "\n",
    "# vis 1 stable\n",
    "# http://localhost:8080/demos/indexTutorial.html\n",
    "\n",
    "# vis 2 faster for larger simulations\n",
    "# http://localhost:8080/demos/indexTutorialGraph.html\n",
    "\n",
    "# vis 3 (GPU Shaders) even faster (max 40 timesteps)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "@webio": {
   "lastCommId": null,
   "lastKernelId": null
  },
  "kernelspec": {
   "display_name": "Julia 1.2.0",
   "language": "julia",
   "name": "julia-1.2"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.2.0"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}