{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Using QUIP potentials with Atomic Simulation Environment\n",
    "\n",
    "- quippy `Potential` objects can be used as ASE calculators\n",
    "- Communicate with other packages using ASE as *lingua franca*\n",
    "\n",
    "## Example: vacancy formation energy\n",
    "\n",
    "- Generate structure with `ASE` lattice tools\n",
    "- Stillinger-Weber potential implementation from `QUIP`\n",
    "- Elastic constant fitting routine from `matscipy`, internal relaxations with `ASE` FIRE minimiser"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25      -34.635777*       0.3247\n",
      "LBFGS:    1 16:55:25      -34.644590*       0.1504\n",
      "LBFGS:    2 16:55:25      -34.646997*       0.0001\n",
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25      -34.670667*       0.1584\n",
      "LBFGS:    1 16:55:25      -34.672777*       0.0749\n",
      "LBFGS:    2 16:55:25      -34.673385*       0.0000\n",
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25      -34.678737*       0.0000\n",
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25      -34.660845*       0.1508\n",
      "LBFGS:    1 16:55:25      -34.662784*       0.0742\n",
      "LBFGS:    2 16:55:25      -34.663403*       0.0000\n",
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25      -34.617822*       0.2945\n",
      "LBFGS:    1 16:55:25      -34.625262*       0.1477\n",
      "LBFGS:    2 16:55:25      -34.627763*       0.0001\n",
      "Fitting C_11\n",
      "Strain array([-0.02, -0.01,  0.  ,  0.01,  0.02])\n",
      "Stress array([-2.56044687, -1.01247671,  0.5027424 ,  1.98366491,  3.42893711]) GPa\n",
      "Cij (gradient) / GPa    :     149.74909575669915\n",
      "Error in Cij / GPa      :     1.1696996170085603\n",
      "Correlation coefficient :     0.9999084935045536\n",
      "Setting C11 (1) to 0.934660 +/- 0.007301\n",
      "\n",
      "\n",
      "Fitting C_21\n",
      "Strain array([-0.02, -0.01,  0.  ,  0.01,  0.02])\n",
      "Stress array([-1.07663577, -0.26643655,  0.5027424 ,  1.23345414,  1.92818198]) GPa\n",
      "Cij (gradient) / GPa    :     75.0952617697293\n",
      "Error in Cij / GPa      :     1.3149075235415504\n",
      "Correlation coefficient :     0.9995404242109733\n",
      "Setting C21 (7) to 0.468708 +/- 0.008207\n",
      "\n",
      "\n",
      "Fitting C_31\n",
      "Strain array([-0.02, -0.01,  0.  ,  0.01,  0.02])\n",
      "Stress array([-1.07663577, -0.26643655,  0.5027424 ,  1.23345414,  1.92818198]) GPa\n",
      "Cij (gradient) / GPa    :     75.09526176972929\n",
      "Error in Cij / GPa      :     1.31490752354155\n",
      "Correlation coefficient :     0.9995404242109733\n",
      "Updating C31 (7) with value 0.468708 +/- 0.008207\n",
      "\n",
      "\n",
      "Fitting C_44\n",
      "Strain array([-0.02, -0.01,  0.  ,  0.01,  0.02])\n",
      "Stress array([-1.13572340e+00, -5.65842409e-01, -9.46072689e-15,  5.60142655e-01,\n",
      "        1.11304586e+00]) GPa\n",
      "Cij (gradient) / GPa    :     56.23523568430934\n",
      "Error in Cij / GPa      :     0.19437884854805132\n",
      "Correlation coefficient :     0.9999820790695022\n",
      "Setting C44 (4) to 0.350993 +/- 0.001213\n",
      "\n",
      "\n",
      "[[b C11 b C12 b C12 b     b     b    ]\n",
      " [b C12 b C11 b C12 b     b     b    ]\n",
      " [b C12 b C12 b C11 b     b     b    ]\n",
      " [b     b     b     b C44 b     b    ]\n",
      " [b     b     b     b     b C44 b    ]\n",
      " [b     b     b     b     b     b C44]]\n",
      "\n",
      " = \n",
      "\n",
      "[[149.75  75.1   75.1    0.     0.     0.  ]\n",
      " [ 75.1  149.75  75.1    0.     0.     0.  ]\n",
      " [ 75.1   75.1  149.75   0.     0.     0.  ]\n",
      " [  0.     0.     0.    56.24   0.     0.  ]\n",
      " [  0.     0.     0.     0.    56.24   0.  ]\n",
      " [  0.     0.     0.     0.     0.    56.24]]\n",
      "C_11 = 149.75 +/- 1.17 GPa\n",
      "C_12 = 75.10 +/- 1.31 GPa\n",
      "C_44 = 56.24 +/- 0.19 GPa\n",
      "       Step     Time          Energy         fmax\n",
      "*Force-consistent energies used in optimization.\n",
      "LBFGS:    0 16:55:25     -927.087471*       0.8332\n",
      "LBFGS:    1 16:55:25     -927.431001*       0.4667\n",
      "LBFGS:    2 16:55:25     -927.618490*       0.1404\n",
      "LBFGS:    3 16:55:25     -927.627345*       0.1185\n",
      "LBFGS:    4 16:55:25     -927.645023*       0.0525\n",
      "LBFGS:    5 16:55:25     -927.647485*       0.0567\n",
      "LBFGS:    6 16:55:25     -927.652217*       0.0421\n",
      "LBFGS:    7 16:55:25     -927.653638*       0.0372\n",
      "LBFGS:    8 16:55:25     -927.654968*       0.0298\n",
      "LBFGS:    9 16:55:25     -927.655716*       0.0221\n",
      "LBFGS:   10 16:55:25     -927.656230*       0.0185\n",
      "LBFGS:   11 16:55:25     -927.656496*       0.0136\n",
      "LBFGS:   12 16:55:25     -927.656686*       0.0109\n",
      "LBFGS:   13 16:55:25     -927.656814*       0.0104\n",
      "LBFGS:   14 16:55:25     -927.656908*       0.0091\n",
      "LBFGS:   15 16:55:25     -927.656982*       0.0072\n",
      "LBFGS:   16 16:55:25     -927.657045*       0.0061\n",
      "LBFGS:   17 16:55:25     -927.657090*       0.0049\n",
      "LBFGS:   18 16:55:25     -927.657121*       0.0045\n",
      "LBFGS:   19 16:55:25     -927.657144*       0.0046\n",
      "LBFGS:   20 16:55:25     -927.657163*       0.0033\n",
      "LBFGS:   21 16:55:25     -927.657178*       0.0029\n",
      "LBFGS:   22 16:55:25     -927.657189*       0.0027\n",
      "LBFGS:   23 16:55:25     -927.657199*       0.0024\n",
      "LBFGS:   24 16:55:25     -927.657207*       0.0025\n",
      "LBFGS:   25 16:55:25     -927.657212*       0.0021\n",
      "LBFGS:   26 16:55:25     -927.657216*       0.0016\n",
      "LBFGS:   27 16:55:25     -927.657218*       0.0012\n",
      "LBFGS:   28 16:55:25     -927.657220*       0.0013\n",
      "LBFGS:   29 16:55:25     -927.657221*       0.0010\n",
      "LBFGS:   30 16:55:25     -927.657222*       0.0012\n",
      "LBFGS:   31 16:55:25     -927.657223*       0.0010\n",
      "LBFGS:   32 16:55:25     -927.657224*       0.0008\n",
      "LBFGS:   33 16:55:25     -927.657225*       0.0006\n",
      "LBFGS:   34 16:55:25     -927.657225*       0.0006\n",
      "LBFGS:   35 16:55:25     -927.657225*       0.0005\n",
      "LBFGS:   36 16:55:25     -927.657226*       0.0004\n",
      "LBFGS:   37 16:55:25     -927.657226*       0.0004\n",
      "LBFGS:   38 16:55:25     -927.657226*       0.0003\n",
      "LBFGS:   39 16:55:25     -927.657226*       0.0002\n",
      "LBFGS:   40 16:55:25     -927.657226*       0.0002\n",
      "LBFGS:   41 16:55:25     -927.657226*       0.0002\n",
      "LBFGS:   42 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   43 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   44 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   45 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   46 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   47 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   48 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   49 16:55:25     -927.657226*       0.0001\n",
      "LBFGS:   50 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   51 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   52 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   53 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   54 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   55 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   56 16:55:25     -927.657226*       0.0000\n",
      "LBFGS:   57 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   58 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   59 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   60 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   61 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   62 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   63 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   64 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   65 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   66 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   67 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   68 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   69 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   70 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   71 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   72 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   73 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   74 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   75 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   76 16:55:26     -927.657226*       0.0000\n",
      "LBFGS:   77 16:55:26     -927.657226*       0.0000\n",
      "SW vacancy formation energy 4.333840201785051 eV\n"
     ]
    }
   ],
   "source": [
    "from ase.build import bulk\n",
    "from ase.optimize import LBFGS\n",
    "from quippy.potential import Potential\n",
    "\n",
    "si = bulk('Si', a=5.44, cubic=True)\n",
    "sw_pot = Potential('IP SW', param_str=\"\"\"\n",
    "<SW_params n_types=\"3\" label=\"PRB_31_plus_H_Ge\">\n",
    "<per_type_data type=\"1\" atomic_num=\"14\" />\n",
    "<per_pair_data atnum_i=\"14\" atnum_j=\"14\" AA=\"7.049556277\" BB=\"0.6022245584\"\n",
    "      p=\"4\" q=\"0\" a=\"1.80\" sigma=\"2.0951\" eps=\"2.1675\" />\n",
    "<per_triplet_data atnum_c=\"14\" atnum_j=\"14\" atnum_k=\"14\"\n",
    "      lambda=\"21.0\" gamma=\"1.20\" eps=\"2.1675\" />\n",
    "</SW_params>\n",
    "\"\"\") # call into Fortran code\n",
    "si.set_calculator(sw_pot)\n",
    "e_bulk_per_atom = si.get_potential_energy()/len(si)\n",
    "\n",
    "# call general purpose elastic constants calculator \n",
    "#   using ASE Atoms and QUIP Potential\n",
    "from matscipy.elasticity import fit_elastic_constants\n",
    "Cij = fit_elastic_constants(si, optimizer=LBFGS,\n",
    "                            symmetry='cubic', logfile='-')\n",
    "vac1 = si.copy()\n",
    "vac1 *= (3, 3, 3)\n",
    "half_cell = np.diag(vac1.cell)/2.\n",
    "vac_atom = ((vac1.positions - half_cell)**2).sum(axis=1).argmin()\n",
    "del vac1[vac_atom]\n",
    "\n",
    "vac1.set_calculator(sw_pot)\n",
    "vac1.rattle(0.01)\n",
    "\n",
    "opt = LBFGS(vac1)\n",
    "opt.run(fmax=1e-6)\n",
    "e_vac = vac1.get_potential_energy() - e_bulk_per_atom*len(vac1)\n",
    "print('SW vacancy formation energy', e_vac, 'eV')"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "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.6.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
