{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Viscoplastic material\n",
    "\n",
    "Small example, how to create a material model with viscoplastic properties. Formulation is done in context of small strains"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "using ForwardDiff\n",
    "using PyPlot"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "6x6 Array{Float64,2}:\n",
       "     2.04615e5  87692.3        87692.3        0.0        0.0        0.0      \n",
       " 87692.3            2.04615e5  87692.3        0.0        0.0        0.0      \n",
       " 87692.3        87692.3            2.04615e5  0.0        0.0        0.0      \n",
       "     0.0            0.0            0.0        1.16923e5  0.0        0.0      \n",
       "     0.0            0.0            0.0        0.0        1.16923e5  0.0      \n",
       "     0.0            0.0            0.0        0.0        0.0        1.16923e5"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "\n",
    "\"\"\"\n",
    "Hooke isotropic stiffness tensor\n",
    "\"\"\"\n",
    "function hookeStiffnessTensor(E, ν)\n",
    "    a = 1 - ν\n",
    "    b = 1 - 2*ν\n",
    "    c = 1 + ν\n",
    "    multiplier = E / (b * c)\n",
    "    return Float64[a ν ν 0 0 0;\n",
    "                   ν a ν 0 0 0;\n",
    "                   ν ν a 0 0 0;\n",
    "                   0 0 0 b 0 0;\n",
    "                   0 0 0 0 b 0;\n",
    "                   0 0 0 0 0 b].*multiplier\n",
    "end\n",
    "\n",
    "# Pick material values\n",
    "E = 152.0e3\n",
    "ν =  0.3\n",
    "C = hookeStiffnessTensor(E, ν)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "calculate_stress (generic function with 1 method)"
      ]
     },
     "execution_count": 39,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# Equations can be found from: http://mms2.ensmp.fr/msi_paris/transparents/Georges_Cailletaud/2013-GC-plas3D.pdf\n",
    "\n",
    "\"\"\"\n",
    "J2 plasticity\n",
    "\"\"\"\n",
    "function J(σ)\n",
    "    e1 = (σ[1] - σ[2])^2\n",
    "    e2 = (σ[2] - σ[3])^2\n",
    "    e3 = (σ[3] - σ[1])^2\n",
    "    e4 = σ[4]^2 \n",
    "    e5 = σ[5]^2\n",
    "    e6 = σ[6]^2\n",
    "    return sqrt((e1 + e2 + e3 + 6 * (e4 + e5 + e6)) / 2.)\n",
    "end\n",
    "\n",
    "\"\"\"\n",
    "Yield function\n",
    "\"\"\"\n",
    "function f(σ, σ_y)\n",
    "    return J(σ) - σ_y\n",
    "end\n",
    "\n",
    "\"\"\"\n",
    "Viscoplastic potential\n",
    "\n",
    "Parameters\n",
    "----------\n",
    "    f_val: float\n",
    "        Yield function value\n",
    "    n: float\n",
    "        Material constant\n",
    "    K: float\n",
    "        Material constant\n",
    "\"\"\"\n",
    "function viscoplastic_potential(f_val, n, K)\n",
    "    n_1 = n+1\n",
    "    return K / n_1 * ( f_val./ K) ^ n_1\n",
    "end\n",
    "\n",
    "\"\"\"\n",
    "Function for calculating stress\n",
    "\"\"\"\n",
    "function calculate_stress(σ_old, dϵ, C, dt, σ_y, n, K)\n",
    "    σ_new = σ_old + C * dϵ * dt\n",
    "    if f(σ_new, σ_y) > 0\n",
    "        \n",
    "        # Viscoplastic potential derivated via ForwardDiff\n",
    "        visco_wrap(x) = viscoplastic_potential(f(x, σ_y), n, K)\n",
    "        dϵ_vp = ForwardDiff.gradient(visco_wrap)\n",
    "        σ_new = σ_old + C * (dϵ - dϵ_vp(σ_new)) * dt\n",
    "    end\n",
    "    return σ_new\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 75,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "steps = 30\n",
    "\n",
    "ϵ_hist = zeros(6)\n",
    "max_strain = 0.0001\n",
    "ϵ_hist[1] = max_strain\n",
    "ϵ_hist[2] = max_strain*-0.3\n",
    "ϵ_hist[3] = max_strain*-0.3;"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Plotting with three different $dt$"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 78,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "ϵ_tot_1 = zeros(6)\n",
    "ϵ_tot_2 = zeros(6)\n",
    "ϵ_tot_3 = zeros(6)\n",
    "\n",
    "nσ_1 = zeros(6)\n",
    "nσ_2 = zeros(6)\n",
    "nσ_3 = zeros(6)\n",
    "\n",
    "dt_1 = 0.01\n",
    "dt_2 = 0.1\n",
    "dt_3 = 0.4\n",
    "\n",
    "σ_1 = []\n",
    "σ_2 = []\n",
    "σ_3 = []\n",
    "\n",
    "ϵ_1 = []\n",
    "ϵ_2 = []\n",
    "ϵ_3 = []\n",
    "\n",
    "σ_y = 150.0\n",
    "nn = 0.92\n",
    "K = 180.0e3\n",
    "\n",
    "for n=1:steps\n",
    "    dϵ_1 = ϵ_hist / dt_1\n",
    "    dϵ_2 = ϵ_hist / dt_2\n",
    "    dϵ_3 = ϵ_hist / dt_3\n",
    "    \n",
    "    nσ_1 = calculate_stress(nσ_1, dϵ_1, C, dt_1, σ_y, nn, K)\n",
    "    nσ_2 = calculate_stress(nσ_2, dϵ_2, C, dt_2, σ_y, nn, K)\n",
    "    nσ_3 = calculate_stress(nσ_3, dϵ_3, C, dt_3, σ_y, nn, K)\n",
    "    \n",
    "    ϵ_tot_1 += dϵ_1 * dt_1\n",
    "    ϵ_tot_2 += dϵ_2 * dt_2\n",
    "    ϵ_tot_3 += dϵ_3 * dt_3\n",
    "    \n",
    "    push!(σ_1, nσ_1[1])\n",
    "    push!(σ_2, nσ_2[1])\n",
    "    push!(σ_3, nσ_3[1])\n",
    "    \n",
    "    push!(ϵ_1, ϵ_tot_1[1])\n",
    "    push!(ϵ_2, ϵ_tot_2[1])\n",
    "    push!(ϵ_3, ϵ_tot_3[1])\n",
    "end"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 82,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 47108 characters]",
      "text/plain": [
       "PyPlot.Figure(PyObject <matplotlib.figure.Figure object at 0x7f8692d9c7d0>)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "PyObject <matplotlib.text.Text object at 0x7f8692cf6b10>"
      ]
     },
     "execution_count": 82,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "PyPlot.plot(ϵ_1, σ_1)\n",
    "PyPlot.plot(ϵ_2, σ_2)\n",
    "PyPlot.plot(ϵ_1, σ_3)\n",
    "PyPlot.xlabel(\"Total strain\")\n",
    "PyPlot.ylabel(\"Stress\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.4.6-pre",
   "language": "julia",
   "name": "julia-0.4"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.4.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
