{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "300"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "using JuliaFEM\n",
    "\n",
    "using JuliaFEM.Core: Node, Element, Seg2, Tri3, Quad4\n",
    "using JuliaFEM.Core: Problem, FieldProblem, BoundaryProblem, Dirichlet, Elasticity, Mortar\n",
    "using JuliaFEM.Core: Solver, SparseMatrixCOO\n",
    "using JuliaFEM.Core: get_elements, update!, calculate_normal_tangential_coordinates!,\n",
    "get_connectivity, get_field_assembly, get_boundary_problems, handle_overconstraint_error!\n",
    "\n",
    "using JuliaFEM.Preprocess: parse_aster_med_file\n",
    "\n",
    "import JuliaFEM.Core: solve_linear_system\n",
    "\n",
    "using PyPlot\n",
    "\n",
    "ENV[\"COLUMNS\"] = 300"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "plot_segmentation (generic function with 1 method)"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function plot_it(field_problem, scaling_factor=1, time=0.0; show_undeformed=true,\n",
    "    show_deformed=true, show_node_ids=true, equal_axis=true, xmin=-1000, ymin=-1000, xmax=1000, ymax=1000)\n",
    "\n",
    "    function in_window(X)\n",
    "        xmin < X[1] < xmax || return false\n",
    "        ymin < X[2] < ymax || return false\n",
    "        return true\n",
    "    end\n",
    "\n",
    "    for element in field_problem.elements\n",
    "        conn = get_connectivity(element)\n",
    "        X = element(\"geometry\", time)\n",
    "        \n",
    "        u = element(\"displacement\", time)\n",
    "        x = X + scaling_factor*u\n",
    "\n",
    "        if show_undeformed\n",
    "            # undeformed\n",
    "            for i=1:length(X)\n",
    "                in_window(X[i]) || continue\n",
    "                px1 = X[i][1]\n",
    "                py1 = X[i][2]\n",
    "                px2 = X[mod(i,length(X))+1][1]\n",
    "                py2 = X[mod(i,length(X))+1][2]\n",
    "                PyPlot.plot([px1, px2], [py1, py2], \"k-\", alpha=0.5, label=\"undeformed\")\n",
    "            end\n",
    "        end\n",
    "\n",
    "        if show_deformed\n",
    "            # deformed\n",
    "            for i=1:length(x)\n",
    "                in_window(x[i]) || continue\n",
    "                px1 = x[i][1]\n",
    "                py1 = x[i][2]\n",
    "                px2 = x[mod(i,length(x))+1][1]\n",
    "                py2 = x[mod(i,length(x))+1][2]\n",
    "                PyPlot.plot([px1, px2], [py1, py2], \"g-\", alpha=0.5, label=\"deformed\")\n",
    "            end\n",
    "        end\n",
    "\n",
    "        if show_node_ids\n",
    "            for (i, c) in enumerate(conn)\n",
    "                in_window(x[i]) || continue\n",
    "                PyPlot.text(x[i][1], x[i][2], \"$c\")\n",
    "            end\n",
    "        end\n",
    "        \n",
    "    end\n",
    "\n",
    "    if equal_axis\n",
    "        PyPlot.axis(\"equal\")\n",
    "    end\n",
    "    #PyPlot.grid()\n",
    "\n",
    "end\n",
    "\n",
    "using JuliaFEM.Core: project_from_master_to_slave, project_from_slave_to_master\n",
    "\n",
    "function plot_normals(contact_problem, time, scale=3)\n",
    "    for element in get_elements(contact_problem)\n",
    "        X1 = element(\"geometry\", [-1.0], time)\n",
    "        X2 = element(\"geometry\", [ 1.0], time)\n",
    "        n1 = element(\"normal-tangential coordinates\", [-1.0], time)\n",
    "        n2 = element(\"normal-tangential coordinates\", [ 1.0], time)\n",
    "        plot([X1[1], X1[1]+scale*n1[1]], [X1[2], X1[2]+scale*n1[2]], \"-b\")\n",
    "        plot([X2[1], X2[1]+scale*n2[1]], [X2[2], X2[2]+scale*n2[2]], \"-b\")\n",
    "    end\n",
    "end\n",
    "\n",
    "function plot_contact_segmentation(slave_element, time)\n",
    "    for master_element in slave_element[\"master elements\"]\n",
    "        xi1a = project_from_master_to_slave(slave_element, master_element, [-1.0])\n",
    "        xi1b = project_from_master_to_slave(slave_element, master_element, [ 1.0])\n",
    "        xi1 = clamp([xi1a xi1b], -1.0, 1.0)\n",
    "        l = 1/2*(xi1[2]-xi1[1])\n",
    "        if abs(l) < 1.0e-9\n",
    "            #info(\"no contribution\")\n",
    "        end\n",
    "        Xs1 = slave_element(\"geometry\", [xi1[1]], time)\n",
    "        Xs2 = slave_element(\"geometry\", [xi1[2]], time)\n",
    "        xi2a = project_from_slave_to_master(slave_element, master_element, [xi1[1]])\n",
    "        xi2b = project_from_slave_to_master(slave_element, master_element, [xi1[2]])\n",
    "        Xm1 = master_element(\"geometry\", xi2a, time)\n",
    "        Xm2 = master_element(\"geometry\", xi2b, time)\n",
    "        plot([Xs1[1], Xm1[1]], [Xs1[2], Xm1[2]], \"-r\", alpha=0.3)\n",
    "        plot([Xs2[1], Xm2[1]], [Xs2[2], Xm2[2]], \"-r\", alpha=0.3)\n",
    "    end\n",
    "end\n",
    "\n",
    "function plot_segmentation(contact_problem)\n",
    "    for (i, element) in enumerate(get_elements(contact_problem))\n",
    "        haskey(element, \"master elements\") || continue\n",
    "        plot_contact_segmentation(element, 0.0)\n",
    "    end\n",
    "end\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: normal direction on slave side = [0.8944271909999159 0.4472135954999579]\n"
     ]
    }
   ],
   "source": [
    "function get_test_problem_1()\n",
    "\n",
    "    gap = [0.5, 0.0]\n",
    "    nodes = Dict{Int64, Node}(\n",
    "        1 => [0.0, 0.0],\n",
    "        2 => [2.0, 0.0],\n",
    "        3 => [1.0, 2.0],\n",
    "        4 => [0.0, 2.0],\n",
    "        5 => [2.0, 0.0]+gap,\n",
    "        6 => [4.0, 0.0]+gap,\n",
    "        7 => [4.0, 1.0]+gap,\n",
    "        8 => [2.0, 1.0]+gap)\n",
    "\n",
    "    E = 288.0\n",
    "    nu = 1.0/3.0\n",
    "\n",
    "    # field problem is plane stress linear elasticity\n",
    "    element1 = Quad4([1, 2, 3, 4])\n",
    "    element2 = Quad4([5, 6, 7, 8])\n",
    "    update!([element1, element2], \"geometry\", nodes)\n",
    "    update!([element1, element2], \"youngs modulus\", E)\n",
    "    update!([element1, element2], \"poissons ratio\", nu)\n",
    "    field_problem = Problem(Elasticity, \"block\", 2)\n",
    "    field_problem.properties.formulation = :plane_stress\n",
    "    push!(field_problem, element1, element2)\n",
    "\n",
    "    # dirichlet boundary conditions\n",
    "    bc1 = Seg2([1, 4])\n",
    "    bc2 = Seg2([6, 7])\n",
    "    update!([bc1, bc2], \"geometry\", nodes)\n",
    "    update!(bc1, \"displacement 1\",  0.0)\n",
    "    update!(bc1, \"displacement 2\",  0.0)\n",
    "    update!(bc2, \"displacement 1\",  0.0)\n",
    "    update!(bc2, \"displacement 2\",  0.0)\n",
    "    # name, unknown field, unknown field dimension\n",
    "    boundary_problem_1 = Problem(Dirichlet, \"ends\", 2, \"displacement\")\n",
    "    push!(boundary_problem_1, bc1, bc2)\n",
    "\n",
    "    # symmetry boundary condition\n",
    "    bc3 = Seg2([1, 2])\n",
    "    bc4 = Seg2([5, 6])\n",
    "    update!([bc3, bc4], \"geometry\", nodes)\n",
    "    update!([bc3, bc4], \"displacement 2\", 0.0)\n",
    "    boundary_problem_2 = Problem(Dirichlet, \"symmetry x-line\", 2, \"displacement\")\n",
    "    push!(boundary_problem_2, bc3, bc4)\n",
    "    \n",
    "    # mortar boundary condition between blocks (set left side as non-mortar side)\n",
    "    bc5 = Seg2([3, 2])\n",
    "    bc6 = Seg2([8, 5])\n",
    "    update!([bc5, bc6], \"geometry\", nodes)\n",
    "    calculate_normal_tangential_coordinates!(bc5, 0.0)\n",
    "    bc5[\"master elements\"] = [bc6]\n",
    "    boundary_problem_3 = Problem(Mortar, \"contact between bodies\", 2, \"displacement\")\n",
    "    push!(boundary_problem_3, bc5, bc6)\n",
    "    nt = bc5(\"normal-tangential coordinates\", [0.0], 0.0)[:,1]\n",
    "    info(\"normal direction on slave side = $(nt')\")\n",
    "\n",
    "    return field_problem, boundary_problem_1, boundary_problem_2, boundary_problem_3\n",
    "end\n",
    "field_problem, boundary_problem_1, boundary_problem_2, boundary_problem_3 = get_test_problem_1();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "collapsed": false,
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: normal direction on slave side = [0.8944271909999159 0.4472135954999579]\n",
      "INFO: solving linear system of 4 problems.\n",
      "INFO: System is overconstrained by 2 dofs.\n",
      "INFO: Overconstrained_nodes: 1, 6.\n",
      "INFO: Following dofs already constrained: 2, 12.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 1 with dofs 1, 2:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 1: ⋯ + 1.0*λ₁ ⋯\n",
      "INFO: dof 2: ⋯ + 1.0*λ₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 1: 1.0*u₁ = 0.0\n",
      "INFO: dof 2: 1.0*u₂ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 2: ⋯ + 1.0*λ₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 2: 1.0*u₂ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 2: 1.0*u₂ = 0.0\n",
      "INFO: \n",
      "INFO: \n",
      "INFO: SUMMARY for node id 6 with dofs 11, 12:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 11: ⋯ + 0.5*λ₁₁ ⋯\n",
      "INFO: dof 12: ⋯ + 0.5*λ₁₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 11: 0.5*u₁₁ = 0.0\n",
      "INFO: dof 12: 0.5*u₁₂ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 12: ⋯ + 1.0*λ₁₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 12: 1.0*u₁₂ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 12: 1.0*u₁₂ = 0.0\n",
      "INFO: \n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 2.\n",
      "INFO: Following dofs already constrained: 4.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 2 with dofs 3, 4:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 4: ⋯ + 1.0*λ₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 4: 1.0*u₄ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 3: ⋯ + 0.57*λ₃ ⋯\n",
      "INFO: dof 4: ⋯ + 0.57*λ₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 3: 0.51*u₃ + 0.255*u₄ - 0.383*u₉ - 0.191*u₁₀ - 0.128*u₁₅ - 0.064*u₁₆ = 0.319\n",
      "INFO: dof 4: 0.255*u₃ - 0.51*u₄ - 0.191*u₉ + 0.383*u₁₀ - 0.064*u₁₅ + 0.128*u₁₆ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 3: 0.51*u₃ + 0.255*u₄ - 0.383*u₉ - 0.191*u₁₀ - 0.128*u₁₅ - 0.064*u₁₆ = 0.319\n",
      "INFO: dof 10: 1.0*u₁₀ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 4: 0.255*u₃ - 0.51*u₄ - 0.191*u₉ + 0.383*u₁₀ - 0.064*u₁₅ + 0.128*u₁₆ = 0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 1.722184181213379 seconds. norm = 0.7572029587976586\n",
      "INFO: solving linear system of 4 problems.\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 23552 characters]",
      "text/plain": [
       "PyPlot.Figure(PyObject <matplotlib.figure.Figure object at 0x7f43da840390>)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "field_problem, boundary_problem_1, boundary_problem_2, boundary_problem_3 = get_test_problem_1()\n",
    "solver = Solver(\"solve block problem\")\n",
    "push!(solver, field_problem, boundary_problem_1, boundary_problem_2, boundary_problem_3)\n",
    "#solver.is_linear_system = true\n",
    "call(solver)\n",
    "plot_it(field_problem)\n",
    "plot_segmentation(boundary_problem_3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: System is overconstrained by 2 dofs.\n",
      "INFO: Overconstrained_nodes: 1, 6.\n",
      "INFO: Following dofs already constrained: 2, 12.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 1 with dofs 1, 2:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 1: ⋯ + 1.0*λ₁ ⋯\n",
      "INFO: dof 2: ⋯ + 1.0*λ₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 1: 1.0*u₁ = 0.0\n",
      "INFO: dof 2: 1.0*u₂ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 2: ⋯ + 1.0*λ₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 2: 1.0*u₂ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 2: 1.0*u₂ = 0.0\n",
      "INFO: \n",
      "INFO: \n",
      "INFO: SUMMARY for node id 6 with dofs 11, 12:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 11: ⋯ + 0.5*λ₁₁ ⋯\n",
      "INFO: dof 12: ⋯ + 0.5*λ₁₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 11: 0.5*u₁₁ = 0.0\n",
      "INFO: dof 12: 0.5*u₁₂ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 12: ⋯ + 1.0*λ₁₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 12: 1.0*u₁₂ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 12: 1.0*u₁₂ = 0.0\n",
      "INFO: \n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 2.\n",
      "INFO: Following dofs already constrained: 4.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 2 with dofs 3, 4:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 4: ⋯ + 1.0*λ₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 4: 1.0*u₄ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 3: ⋯ + 0.57*λ₃ ⋯\n",
      "INFO: dof 4: ⋯ + 0.57*λ₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 3: 0.51*u₃ + 0.255*u₄ - 0.383*u₉ - 0.191*u₁₀ - 0.128*u₁₅ - 0.064*u₁₆ = 0.319\n",
      "INFO: dof 4: 0.255*u₃ - 0.51*u₄ - 0.191*u₉ + 0.383*u₁₀ - 0.064*u₁₅ + 0.128*u₁₆ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 3: 0.51*u₃ + 0.255*u₄ - 0.383*u₉ - 0.191*u₁₀ - 0.128*u₁₅ - 0.064*u₁₆ = 0.319\n",
      "INFO: dof 10: 1.0*u₁₀ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 4: 0.255*u₃ - 0.51*u₄ - 0.191*u₉ + 0.383*u₁₀ - 0.064*u₁₅ + 0.128*u₁₆ = 0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.002077817916870117 seconds. norm = 0.7572029587976586\n",
      "INFO: Converged in 2 iterations.\n"
     ]
    }
   ],
   "source": [
    "@assert isapprox(norm(field_problem.assembly.u), 0.7572029587976579)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: [0.24895296909147305 0.18847925373355964]\n",
      "INFO: [-0.12546065165888792 0.0]\n"
     ]
    }
   ],
   "source": [
    "info(field_problem.elements[1](\"displacement\", [ 1.0, -1.0], 0.0)')\n",
    "info(field_problem.elements[2](\"displacement\", [-1.0, -1.0], 0.0)')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Curved interface"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Found 5 element sets: SYM23, LOWER_TO_UPPER, LOAD, SYM13, UPPER_TO_LOWER\n",
      "INFO: created 170 field elements.\n",
      "INFO: slave element UPPER_TO_LOWER: midpoint = [0.4147584594687138,0.40581289439367096], nt coordinate = [0.06698025853929859 -0.995493336386047\n",
      " 0.995493336386047 0.06698025853929859]\n",
      "INFO: # of master elements: 5\n",
      "INFO: # of slave elements: 6\n",
      "INFO: solving linear system of 4 problems.\n",
      "INFO: System is overconstrained by 1 dofs.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function curved_interface_problem(meshfile=\"/geometry/2d_curved_interface/MESH_SPARSE.med\")\n",
    "\n",
    "    mesh = parse_aster_med_file(Pkg.dir(\"JuliaFEM\")*meshfile)\n",
    "    \n",
    "    field_problem = Problem(Elasticity, \"two parts with curved interface\", 2)\n",
    "    field_problem.properties.formulation = :plane_stress\n",
    "\n",
    "    # field problems\n",
    "    mapping = Dict(:QU4 => Quad4, :TR3 => Tri3)\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        haskey(mapping, eltype) || continue\n",
    "        element = mapping[eltype](elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        element[\"youngs modulus\"] = 2880.0\n",
    "        element[\"poissons ratio\"] = 1/3\n",
    "        push!(field_problem, element)\n",
    "    end\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        eltype == :SE2 || continue\n",
    "        elset == :LOAD || continue\n",
    "        element = Seg2(elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        update!(element, \"displacement traction force 2\", -100.0)\n",
    "        push!(field_problem, element)\n",
    "    end\n",
    "\n",
    "    # boundary conditions\n",
    "    sym13 = Problem(Dirichlet, \"SYM13\", 2, \"displacement\")\n",
    "    sym23 = Problem(Dirichlet, \"SYM23\", 2, \"displacement\")\n",
    "\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        eltype == :SE2 || continue\n",
    "        elset == :SYM13 || continue\n",
    "        element = Seg2(elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        push!(sym13, element)\n",
    "    end\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        eltype == :SE2 || continue\n",
    "        elset == :SYM23 || continue\n",
    "        element = Seg2(elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        push!(sym23, element)\n",
    "    end\n",
    "\n",
    "    update!(get_elements(sym13), \"displacement 2\", 0.0)\n",
    "    update!(get_elements(sym23), \"displacement 1\", 0.0)\n",
    "\n",
    "    info(\"created $(length(get_elements(field_problem))) field elements.\")\n",
    "#    info(\"created $(length(get_elements(boundary_problem))) boundary elements.\")\n",
    "\n",
    "    slave_surface = :UPPER_TO_LOWER\n",
    "    master_surface = :LOWER_TO_UPPER\n",
    "\n",
    "    contact = Problem(Mortar, \"tie contact between blocks\", 2, \"displacement\")\n",
    "    master_elements = Element[]\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        eltype == :SE2 || continue\n",
    "        elset == master_surface || continue\n",
    "        element = Seg2(elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        push!(master_elements, element)\n",
    "        push!(contact, element)\n",
    "    end\n",
    "\n",
    "    first = true\n",
    "    slave_elements = Element[]\n",
    "    for (elid, (eltype, elset, elcon)) in mesh[\"connectivity\"]\n",
    "        eltype == :SE2 || continue\n",
    "        elset == slave_surface || continue\n",
    "        element = Seg2(elcon)\n",
    "        update!(element, \"geometry\", mesh[\"nodes\"])\n",
    "        element[\"master elements\"] = master_elements\n",
    "        push!(slave_elements, element)\n",
    "        push!(contact, element)\n",
    "    end\n",
    "    calculate_normal_tangential_coordinates!(slave_elements, 0.0)\n",
    "    if first\n",
    "        element = slave_elements[1]\n",
    "        Q = element(\"normal-tangential coordinates\", [0.0], 0.0)\n",
    "        X = element(\"geometry\", [0.0], 0.0)\n",
    "        info(\"slave element $slave_surface: midpoint = $X, nt coordinate = $Q\")\n",
    "        first = false\n",
    "    end\n",
    "\n",
    "    info(\"# of master elements: $(length(master_elements))\")\n",
    "    info(\"# of slave elements: $(length(slave_elements))\")\n",
    "\n",
    "    return field_problem, sym13, sym23, contact\n",
    "\n",
    "end\n",
    "\n",
    "field_problem, sym13, sym23, contact = curved_interface_problem()\n",
    "solver = Solver(\"solver curved interface\")\n",
    "\n",
    "push!(solver, field_problem, sym13, sym23, contact)\n",
    "\n",
    "#solver.is_linear_system = true\n",
    "call(solver)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 113492 characters]",
      "text/plain": [
       "PyPlot.Figure(PyObject <matplotlib.figure.Figure object at 0x7f43d83f3210>)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(-0.1,1.1,0.3,0.52)"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Overconstrained_nodes: 47.\n",
      "INFO: Following dofs already constrained: 93.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 47 with dofs 93, 94:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 93: ⋯ + 0.062*λ₉₃ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 93: 0.062*u₉₃ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 93: ⋯ + 0.085*λ₉₃ ⋯\n",
      "INFO: dof 94: ⋯ + 0.085*λ₉₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 93: 0.027*u₉ - 0.081*u₁₀ - 0.0*u₁₁ - 0.0*u₁₂ + 0.027*u₉₃ + 0.081*u₉₄ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 94: 0.081*u₉ - 0.027*u₁₀ + 0.0*u₁₁ - 0.0*u₁₂ - 0.081*u₉₃ + 0.027*u₉₄ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 94: 0.081*u₉ - 0.027*u₁₀ + 0.0*u₁₁ - 0.0*u₁₂ - 0.081*u₉₃ + 0.027*u₉₄ = -0.0\n",
      "INFO: dof 9: 0.062*u₉ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 93: 0.027*u₉ - 0.081*u₁₀ - 0.0*u₁₁ - 0.0*u₁₂ + 0.027*u₉₃ + 0.081*u₉₄ = 0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.0029261112213134766 seconds. norm = 0.2117161697202773\n",
      "INFO: solving linear system of 4 problems.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 47.\n",
      "INFO: Following dofs already constrained: 93.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 47 with dofs 93, 94:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 93: ⋯ + 0.062*λ₉₃ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 93: 0.062*u₉₃ = 0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 93: ⋯ + 0.085*λ₉₃ ⋯\n",
      "INFO: dof 94: ⋯ + 0.085*λ₉₄ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 93: 0.027*u₉ - 0.081*u₁₀ - 0.0*u₁₁ - 0.0*u₁₂ + 0.027*u₉₃ + 0.081*u₉₄ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 94: 0.081*u₉ - 0.027*u₁₀ + 0.0*u₁₁ - 0.0*u₁₂ - 0.081*u₉₃ + 0.027*u₉₄ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 94: 0.081*u₉ - 0.027*u₁₀ + 0.0*u₁₁ - 0.0*u₁₂ - 0.081*u₉₃ + 0.027*u₉₄ = -0.0\n",
      "INFO: dof 9: 0.062*u₉ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 93: 0.027*u₉ - 0.081*u₁₀ - 0.0*u₁₁ - 0.0*u₁₂ + 0.027*u₉₃ + 0.081*u₉₄ = 0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.002628803253173828 seconds. norm = 0.2117161697202773\n",
      "INFO: Converged in 2 iterations.\n"
     ]
    }
   ],
   "source": [
    "figure(figsize=(12, 4))\n",
    "plot_it(field_problem; show_undeformed=false, equal_axis=false, show_node_ids=false)\n",
    "xlim(-0.1, 1.1)\n",
    "ylim(0.30, 0.52)\n",
    "axis(\"off\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: Found 6 element sets: SYM23, BLOCK_TO_CYLINDER, CYLINDER_TO_BLOCK, CYLINDER, GROUND, BLOCK\n",
      "INFO: # of master elements: 27\n"
     ]
    }
   ],
   "source": [
    "using JuliaFEM.Preprocess: aster_create_elements\n",
    "\n",
    "function create_hertzian_problem(meshfile=\"/geometry/2d_cylinder_roller_contact/MESH_REFINED_3.med\")\n",
    "\n",
    "    mesh = parse_aster_med_file(Pkg.dir(\"JuliaFEM\")*meshfile)\n",
    "    \n",
    "    body1 = Problem(Elasticity, \"cylinder\", 2)\n",
    "    body1_elements = aster_create_elements(mesh, :CYLINDER, :TR3)\n",
    "    body1.properties.formulation = :plane_strain\n",
    "    update!(body1_elements, \"youngs modulus\", 210e3)\n",
    "    update!(body1_elements, \"poissons ratio\", 0.3)\n",
    "    push!(body1, body1_elements...)\n",
    "\n",
    "    body2 = Problem(Elasticity, \"block\", 2)\n",
    "    body2_elements = aster_create_elements(mesh, :BLOCK, :TR3)\n",
    "    body2.properties.formulation = :plane_strain\n",
    "    update!(body2_elements, \"youngs modulus\", 70.0e3)\n",
    "    update!(body2_elements, \"poissons ratio\", 0.3)\n",
    "    push!(body2, body2_elements...)\n",
    "\n",
    "    # boundary conditions\n",
    "    bc1 = Problem(Dirichlet, \"ground\", 2, \"displacement\")\n",
    "    bc1_elements = aster_create_elements(mesh, :GROUND, :SE2)\n",
    "    update!(bc1_elements, \"displacement\", 0.0)\n",
    "    push!(bc1, bc1_elements...)\n",
    "\n",
    "    bc2 = Problem(Dirichlet, \"symmetry line\", 2, \"displacement\")\n",
    "    bc2_elements = aster_create_elements(mesh, :SYM23, :SE2)\n",
    "    update!(bc2_elements, \"displacement 1\", 0.0)\n",
    "    push!(bc2, bc2_elements...)\n",
    "\n",
    "    # contact\n",
    "    bc3 = Problem(Mortar, \"contact interface\", 2, \"displacement\")\n",
    "    bc3_slave_elements = aster_create_elements(mesh, :CYLINDER_TO_BLOCK, :SE2)\n",
    "    bc3_master_elements = aster_create_elements(mesh, :BLOCK_TO_CYLINDER, :SE2)\n",
    "    update!(bc3_slave_elements, \"master elements\", bc3_master_elements)\n",
    "    calculate_normal_tangential_coordinates!(bc3_slave_elements, 0.0)\n",
    "    push!(bc3, bc3_slave_elements...)\n",
    "    push!(bc3, bc3_master_elements...)\n",
    "    info(\"# of master elements: $(length(bc3_master_elements))\")\n",
    "    info(\"# of slave elements: $(length(bc3_slave_elements))\")\n",
    "    fel = bc3_slave_elements[1]\n",
    "    n = fel(\"normals\", [0.0], 0.0)\n",
    "    X1 = fel(\"geometry\", [-1.0], 0.0)\n",
    "    X2 = fel(\"geometry\", [ 1.0], 0.0)\n",
    "    info(\"normal direction of first contact element: $n\")\n",
    "    info(\"element geometry: from $X1 to $X2\")\n",
    "\n",
    "    return body1, body2, bc1, bc2, bc3\n",
    "\n",
    "end\n",
    "create_hertzian_problem();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: # of slave elements: 37\n",
      "INFO: normal direction of first contact element: [0.33004993336440486,-0.9438504633679171]\n",
      "INFO: element geometry: from [17.19187882421571,203.04854312703935] to [15.811388300842912,202.56583509747463]\n",
      "INFO: Found 6 element sets: SYM23, BLOCK_TO_CYLINDER, CYLINDER_TO_BLOCK, CYLINDER, GROUND, BLOCK\n",
      "INFO: # of master elements: 27\n",
      "INFO: # of slave elements: 37\n",
      "INFO: normal direction of first contact element: [0.33004993336440486,-0.9438504633679171]\n",
      "INFO: element geometry: from [17.19187882421571,203.04854312703935] to [15.811388300842912,202.56583509747463]\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.14606285095214844 seconds. norm = 85.08623527509272\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.026980876922607422 seconds. norm = 59.83136581257375\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.02696514129638672 seconds. norm = 52.776611096750806\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.02712392807006836 seconds. norm = 48.47259883552261\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.03039407730102539 seconds. norm = 46.17282278249895\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.032618045806884766 seconds. norm = 45.75796140962765\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.037216901779174805 seconds. norm = 45.34459038168802\n",
      "INFO: solving linear system of 5 problems.\n",
      "INFO: Hacking nodal force.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "true"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import JuliaFEM.Core: boundary_assembly_posthook!, field_assembly_posthook!\n",
    "\n",
    "\"\"\" Hack y direction nodal force. \"\"\"\n",
    "function field_assembly_posthook!(solver::Solver, K::SparseMatrixCSC, f::SparseMatrixCSC)\n",
    "    info(\"Hacking nodal force.\")\n",
    "    f[2*(450-1)+2] = -35.0e3/2\n",
    "end\n",
    "\n",
    "body1, body2, bc1, bc2, bc3 = create_hertzian_problem()\n",
    "solver = Solver(\"roller contact\")\n",
    "#solver.is_linear_system = true\n",
    "solver.nonlinear_system_max_iterations = 20\n",
    "bc3.properties.inequality_constraints = true\n",
    "#bc3.properties.normal_condition = :Contact\n",
    "#bc3.properties.tangential_condition = :Slip\n",
    "push!(solver, body1, body2, bc1, bc2, bc3)\n",
    "solver()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "image/png": "[encoded data, 208040 characters]",
      "text/plain": [
       "PyPlot.Figure(PyObject <matplotlib.figure.Figure object at 0x7f43d78a3690>)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(199,202)"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 11.\n",
      "INFO: Following dofs already constrained: 21.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 11 with dofs 21, 22:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: dof 22: ⋯ + 5.0*λ₂₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: dof 22: 5.0*u₂₂ = 0.0\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 21: ⋯ + 5.0*λ₂₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 21: 5.0*u₂₁ = 0.0 <-- overconstrained dof\n",
      "INFO: rank = 1, dofs = 1\n",
      "INFO: algorithm 1 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 21: 1.0*u₂₁ = 0.0\n",
      "INFO: \n",
      "INFO: PDASS: Starting primal-dual active set strategy to determine active constraints\n",
      "INFO: PDASS: contact nodes: [490,491,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: active nodes: [491,581,582,583,584,585,586,587,588,589,590,591,592,593,594,595,596]\n",
      "INFO: PDASS: inactive nodes: [490,561,562,563,564,565,566,567,568,569,570,571,572,573,574,575,576,577,578,579,580]\n",
      "INFO: System is overconstrained by 1 dofs.\n",
      "INFO: Overconstrained_nodes: 491.\n",
      "INFO: Following dofs already constrained: 981.\n",
      "INFO: \n",
      "INFO: SUMMARY for node id 491 with dofs 981, 982:\n",
      "INFO: ----- Current constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.1*u₉₈₁ = -0.0 <-- overconstrained dof\n",
      "INFO: ----- New constraint -----\n",
      "INFO: lambda coefficients in C1 matrix are:\n",
      "INFO: dof 981: ⋯ + 0.1*λ₉₈₁ ⋯\n",
      "INFO: dof 982: ⋯ + 0.1*λ₉₈₂ ⋯\n",
      "INFO: rows in constraint matrix C2 & D\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0 <-- overconstrained dof\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: ----- Related equations -----\n",
      "INFO: dof 982: 0.0*u₁₁₁ + 0.0*u₁₁₃ + 0.0*u₁₁₄ - 0.1*u₁₁₅ - 0.0*u₁₁₆ + 0.1*u₉₈₁ + 0.0*u₉₈₂ = -0.0\n",
      "INFO: dof 115: 0.1*u₁₁₅ = 0.0\n",
      "INFO: algorithm 1 solved issue? false\n",
      "INFO: algorithm 2 solved issue? true\n",
      "INFO: fixed: new setting is\n",
      "INFO: dof 981: 0.0*u₁₁₂ + 0.0*u₁₁₃ - 0.0*u₁₁₄ - 0.0*u₁₁₅ + 0.1*u₁₁₆ + 0.0*u₉₈₁ - 0.1*u₉₈₂ = -0.0\n",
      "INFO: \n",
      "INFO: UMFPACK: solved in 0.027383089065551758 seconds. norm = 45.34459038168802\n",
      "INFO: Converged in 8 iterations.\n"
     ]
    }
   ],
   "source": [
    "fig = PyPlot.figure(figsize=(8,4))\n",
    "plot_it(body1, 1.0; show_node_ids=false, show_undeformed=false,\n",
    "        show_deformed=true, xmin=-1, xmax=30, ymin=190, ymax=210)\n",
    "plot_it(body2, 1.0; show_node_ids=false, show_undeformed=false,\n",
    "        show_deformed=true, xmin=-1, xmax=30, ymin=190, ymax=210)\n",
    "#plot_normals(bc3, 0.0, 1)\n",
    "#grid(\"off\")\n",
    "#axis(\"off\")\n",
    "xlim(0, 10)\n",
    "ylim(199, 202)\n",
    "#legend(loc=2)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [],
   "source": [
    "@assert isapprox(norm(body1.assembly.u), 45.34459038168802)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "pmax = 3585.362230884501\n"
     ]
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "INFO: pn[1] = 3662.35094080636\n"
     ]
    },
    {
     "data": {
      "image/png": "[encoded data, 29940 characters]",
      "text/plain": [
       "PyPlot.Figure(PyObject <matplotlib.figure.Figure object at 0x7f43da89b850>)"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "(0,10)"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "function get_acc_sol()\n",
    "    B = 1\n",
    "    E1 = 210.0e3\n",
    "    E2 = 70.0e3\n",
    "    nu1 = 0.3\n",
    "    nu2 = 0.3\n",
    "    F = 35.0e3\n",
    "    E = 2*E1*E2/(E2*(1-nu1^2) + E1*(1-nu2^2))\n",
    "    R = 50.0\n",
    "    pmax = sqrt(F*E/(2*pi*B*R))\n",
    "    println(\"pmax = $pmax\")\n",
    "    a = sqrt(8*F*R/(pi*B*E))\n",
    "    acc_x = linspace(1.0e-10, a)\n",
    "    acc_p = pmax*sqrt(1-acc_x/a)\n",
    "    return acc_x, acc_p\n",
    "end\n",
    "acc_x, acc_p = get_acc_sol()\n",
    "\n",
    "x = Float64[]\n",
    "pn = Float64[]\n",
    "#xi = linspace(-1, 1, 5)\n",
    "xi = [-1.0, 0.0, 1.0]\n",
    "\n",
    "for element in get_elements(bc3)\n",
    "    haskey(element, \"master elements\") || continue\n",
    "    for k in xi\n",
    "        X = element(\"geometry\", [k], 0.0)\n",
    "        u = element(\"displacement\", [k], 0.0)\n",
    "        pxy = element(\"reaction force\", [k], 0.0)\n",
    "        Q = element(\"normal-tangential coordinates\", [k], 0.0)\n",
    "        pnt = Q'*pxy\n",
    "        push!(x, X[1])\n",
    "        push!(pn, pnt[1])\n",
    "        #plot(X[1], pnt[1], \"bo\")\n",
    "    end\n",
    "end\n",
    "\n",
    "P = sortperm(x)\n",
    "figure(figsize=(5, 5))\n",
    "x = x[P]\n",
    "pn = pn[P]\n",
    "info(\"pn[1] = $(pn[1])\")\n",
    "plot(x, pn, \"k.\")\n",
    "plot(acc_x, acc_p, \"-g\")\n",
    "#    plot(X[1], pxy[1], \"ro\", label=\"x direction\")\n",
    "#    plot(X[1], pxy[2], \"go\", label=\"y direction\")\n",
    "#    plot(X[1], pnt[2], \"bo\", label=\"tangential direction\")\n",
    "xlim(0, 10)\n",
    "#ylim(0, 4200)\n",
    "#legend()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(-8378.501456957838,671.4667011944753)"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "minimum(bc3.assembly.la), maximum(bc3.assembly.la)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 0.4.3",
   "language": "julia",
   "name": "julia-0.4"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "0.4.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 0
}
