{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Do a bandstructure calculation from a completed CASTEP run" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "from __future__ import print_function" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "%aiida\n", "from ase import Atoms\n", "import numpy as np\n", "StructureData = DataFactory('structure')\n", "ParameterData = DataFactory('parameter')\n", "KpointsData = DataFactory('array.kpoints')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Query the database\n", "We locate the finished calculations. You can just use `verdi calculation list -p 5 -a` to list all \n", "calculations in the last five days. \n", "\n", "Here, we demonstrate construction of the queries directly.\n", "The database can be queried using filters and the relations. Effectively, we select a portion of the graph and project out the results. \n", "More details [here](https://aiida-core.readthedocs.io/en/v0.12.3/querying/querybuilder/usage.html)" ] }, { "cell_type": "code", "execution_count": 55, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "[[233, u'Si SINGLEPOINT', -337.9095919944, u'medium', None],\n", " [224, u'Si BS', None, u'medium', None],\n", " [196, u'Si SINGELPOINT CUT 220', -338.0325703763, None, 220],\n", " [194, u'Si SINGELPOINT CUT 190', -338.0000071338, None, 190],\n", " [192, u'Si SINGELPOINT CUT 160', -337.89984485, None, 160],\n", " [190, u'Si SINGELPOINT CUT 130', -337.7024248975, None, 130],\n", " [188, u'Si SINGELPOINT CUT 100', -338.4519044612, None, 100],\n", " [181, u'Si SINGELPOINT', -338.7362617759, None, 120],\n", " [171, u'Si SINGLEPOINT', -337.9095919907, u'medium', None],\n", " [162, u'Si SINGLEPOINT', -303.9525230982, u'medium', None]]" ] }, "execution_count": 55, "metadata": {}, "output_type": "execute_result" } ], "source": [ "q = QueryBuilder()\n", "q.append(Calculation, filters={'label': {'like':'Si%'},\n", " 'state': 'FINISHED'},\n", " project=['id', 'label'])\n", "q.append(ParameterData, \n", " output_of=Calculation, project=['attributes.total_energy']) # Project the energy\n", "q.append(ParameterData, input_of=Calculation,\n", " edge_filters={\"label\": 'parameters'},\n", " project=[\"attributes.PARAM.basis_precision\", \"attributes.PARAM.cut_off_energy\"]) # Project the input key\n", "q.order_by({Calculation: [{'id': 'desc'}]})\n", "q.all()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Create the CastepSpectralCalculation" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [], "source": [ "SpectralCalc = CalculationFactory('castep.spec')" ] }, { "cell_type": "code", "execution_count": 56, "metadata": {}, "outputs": [], "source": [ "# We select the first calculation\n", "pk = q.first()[0]\n", "sp_calc = load_node(pk) # Load the calculation Node\n", "spec_calc = SpectralCalc.continue_from(sp_calc, restart_type='continuation')" ] }, { "cell_type": "code", "execution_count": 57, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "{u'CELL': {u'snap_to_symmetry': True, u'symmetry_generate': True},\n", " u'PARAM': {u'basis_precision': u'medium',\n", " 'continuation': './parent/aiida.check',\n", " u'fix_occupancy': True,\n", " u'num_dump_cycles': 0,\n", " u'opt_strategy': u'memory',\n", " u'task': 'spectral',\n", " u'write_formatted_density': True},\n", " 'code': ,\n", " 'computer': ,\n", " 'custom_scheduler_commands': '',\n", " 'kpoints': 'Kpoints mesh: 4x4x4 (+0.0,0.0,0.0)',\n", " 'label': u'',\n", " 'pseudos': {u'Si': u'C18'},\n", " 'resources': {},\n", " 'spectral_kpoints': None,\n", " 'structure': {'cell': [[2.6954645, 2.6954645, 0.0],\n", " [2.6954645, 0.0, 2.6954645],\n", " [0.0, 2.6954645, 2.6954645]],\n", " 'formula': 'Si2',\n", " 'label': u'Si'},\n", " 'wallclock': None}" ] }, "execution_count": 57, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The inputs are copied over, note that the 'continuation' keyword is set automaticall\n", "spec_calc.get_castep_input_summary()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Define the Kpoints used for band structure calculation\n", "Recall:\n", "```\n", "%block bs_kpoint_path \n", "0.5 0.25 0.75 ! W\n", "0.5 0.5 0.5 ! L\n", "0.0 0.0 0.0 ! Gamma\n", "0.5 0.0 0.5 ! X\n", "0.5 0.25 0.75 ! W\n", "0.375 0.375 0.75 ! K\n", "%endblock bs_kpoint_path \n", "```\n", "However, rather than putting this directly in the `ParameterData` (which would work as it should), we can define a explicit kpoint path.\n", "Such path may be reused in a layer date for other calculations." ] }, { "cell_type": "code", "execution_count": 58, "metadata": {}, "outputs": [], "source": [ "bs_kpoints = KpointsData()" ] }, { "cell_type": "code", "execution_count": 59, "metadata": { "scrolled": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of kpoints: 44\n" ] }, { "data": { "text/plain": [ "array([[0.5 , 0.25 , 0.75 ],\n", " [0.5 , 0.29166667, 0.70833333],\n", " [0.5 , 0.33333333, 0.66666667],\n", " [0.5 , 0.375 , 0.625 ],\n", " [0.5 , 0.41666667, 0.58333333],\n", " [0.5 , 0.45833333, 0.54166667],\n", " [0.5 , 0.5 , 0.5 ],\n", " [0.46875 , 0.46875 , 0.46875 ],\n", " [0.4375 , 0.4375 , 0.4375 ],\n", " [0.40625 , 0.40625 , 0.40625 ],\n", " [0.375 , 0.375 , 0.375 ],\n", " [0.34375 , 0.34375 , 0.34375 ],\n", " [0.3125 , 0.3125 , 0.3125 ],\n", " [0.28125 , 0.28125 , 0.28125 ],\n", " [0.25 , 0.25 , 0.25 ],\n", " [0.21875 , 0.21875 , 0.21875 ],\n", " [0.1875 , 0.1875 , 0.1875 ],\n", " [0.15625 , 0.15625 , 0.15625 ],\n", " [0.125 , 0.125 , 0.125 ],\n", " [0.09375 , 0.09375 , 0.09375 ],\n", " [0.0625 , 0.0625 , 0.0625 ],\n", " [0.03125 , 0.03125 , 0.03125 ],\n", " [0. , 0. , 0. ],\n", " [0.03846154, 0. , 0.03846154],\n", " [0.07692308, 0. , 0.07692308],\n", " [0.11538462, 0. , 0.11538462],\n", " [0.15384615, 0. , 0.15384615],\n", " [0.19230769, 0. , 0.19230769],\n", " [0.23076923, 0. , 0.23076923],\n", " [0.26923077, 0. , 0.26923077],\n", " [0.30769231, 0. , 0.30769231],\n", " [0.34615385, 0. , 0.34615385],\n", " [0.38461538, 0. , 0.38461538],\n", " [0.42307692, 0. , 0.42307692],\n", " [0.46153846, 0. , 0.46153846],\n", " [0.5 , 0. , 0.5 ],\n", " [0.5 , 0.04166667, 0.54166667],\n", " [0.5 , 0.08333333, 0.58333333],\n", " [0.5 , 0.125 , 0.625 ],\n", " [0.5 , 0.16666667, 0.66666667],\n", " [0.5 , 0.20833333, 0.70833333],\n", " [0.5 , 0.25 , 0.75 ],\n", " [0.4375 , 0.3125 , 0.75 ],\n", " [0.375 , 0.375 , 0.75 ]])" ] }, "execution_count": 59, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bs_kpoints.set_kpoints_path([('W', (0.5, 0.25, 0.75),\n", " 'L', (0.5, 0.5, 0.5),),\n", " ('L', (0.5, 0.5, 0.5),\n", " 'Gamma', (0., 0., 0.)),\n", " ('Gamma', (0., 0., 0.),\n", " 'X', (0.5, 0.0, 0.5)),\n", " ('X', (0.5, 0.0, 0.5), \n", " 'W', (0.5, 0.25, 0.75)),\n", " ('W', (0.5, 0.25, 0.75),\n", " 'K', (0.375, 0.375, 0.75))\n", " ],\n", " kpoint_distance=0.05\n", " )\n", "# The explicity list of kpoints\n", "print('Number of kpoints: ', len(bs_kpoints.get_kpoints()))\n", "bs_kpoints.get_kpoints()" ] }, { "cell_type": "code", "execution_count": 60, "metadata": { "scrolled": true }, "outputs": [ { "data": { "text/plain": [ "{'array|kpoints': [44, 3],\n", " 'label_numbers': [0, 6, 22, 35, 41, 43],\n", " 'labels': ['W', 'L', 'Gamma', 'X', 'W', 'K']}" ] }, "execution_count": 60, "metadata": {}, "output_type": "execute_result" } ], "source": [ "# The labels are also stored\n", "bs_kpoints.get_attrs()" ] }, { "cell_type": "code", "execution_count": 61, "metadata": {}, "outputs": [], "source": [ "# Tell the spectral calculation to use the kpoints list generated\n", "spec_calc.use_spectral_kpoints(bs_kpoints)\n", "spec_calc.update_parameters(spectral_task='bandstructure') # Oop I forgot to set this earlier\n", "# Resources are not copied over - as it is often different from the inital calculation\n", "spec_calc.set_resources({'num_machines':1, 'tot_num_mpiprocs':2})\n", "spec_calc.set_max_wallclock_seconds(1800)\n", "folder, _ = spec_calc.submit_test()" ] }, { "cell_type": "raw", "metadata": {}, "source": [ "# Check the input cell file if you whish\n", "!cat {folder.get_abs_path('aiida.cell')}" ] }, { "cell_type": "code", "execution_count": 62, "metadata": {}, "outputs": [], "source": [ "# Don't forget to label the calculation\n", "spec_calc.label = \"Si BS\"\n", "spec_calc.description = \"A spectral calculation. Reuse the singlepoint calculation previoused generated.\"" ] }, { "cell_type": "code", "execution_count": 63, "metadata": {}, "outputs": [], "source": [ "spec_calc.store_all(); spec_calc.submit()" ] }, { "cell_type": "code", "execution_count": 77, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "# Last daemon state_updater check: 0h:00m:00s ago (at 19:17:07 on 2019-03-20)\n", " PK Creation State Sched. state Computer Type\n", "---- ---------- -------- -------------- ---------- -------------\n", " 162 26m ago FINISHED DONE localhost castep.castep\n", " 171 19m ago FINISHED DONE localhost castep.castep\n", " 181 17m ago FINISHED DONE localhost castep.castep\n", " 188 16m ago FINISHED DONE localhost castep.castep\n", " 190 16m ago FINISHED DONE localhost castep.castep\n", " 192 16m ago FINISHED DONE localhost castep.castep\n", " 194 16m ago FINISHED DONE localhost castep.castep\n", " 196 16m ago FINISHED DONE localhost castep.castep\n", " 224 10m ago FINISHED DONE localhost castep.spec\n", " 233 7m ago FINISHED DONE localhost castep.castep\n", " 241 41s ago COMPUTED DONE localhost castep.spec\n", "\n", "Total results: 11\n", "\n", " JOBID PARTITION NAME USER ST TIME NODES NODELIST(REASON)\n" ] } ], "source": [ "!verdi calculation list -p1 -a\n", "!squeue" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Plot the band structure\n", "The `*bands` file are parsed by `aiida-castep` and the KS eigenvalues can be access directly in python." ] }, { "cell_type": "code", "execution_count": 78, "metadata": {}, "outputs": [], "source": [ "%matplotlib notebook\n", "import matplotlib.pyplot as plt" ] }, { "cell_type": "code", "execution_count": 79, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "u'COMPUTED'" ] }, "execution_count": 79, "metadata": {}, "output_type": "execute_result" } ], "source": [ "spec_calc.get_state()" ] }, { "cell_type": "code", "execution_count": 81, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(44, 14)\n" ] } ], "source": [ "bands_node = spec_calc.out.output_bands\n", "bands_data = bands_node.get_bands()\n", "print(bands_data.shape)" ] }, { "cell_type": "code", "execution_count": 82, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "array([[0.5 , 0.25 , 0.75 ],\n", " [0.5 , 0.29166667, 0.70833333],\n", " [0.5 , 0.33333333, 0.66666667],\n", " [0.5 , 0.375 , 0.625 ],\n", " [0.5 , 0.41666667, 0.58333333],\n", " [0.5 , 0.45833333, 0.54166667],\n", " [0.5 , 0.5 , 0.5 ],\n", " [0.46875 , 0.46875 , 0.46875 ],\n", " [0.4375 , 0.4375 , 0.4375 ],\n", " [0.40625 , 0.40625 , 0.40625 ],\n", " [0.375 , 0.375 , 0.375 ],\n", " [0.34375 , 0.34375 , 0.34375 ],\n", " [0.3125 , 0.3125 , 0.3125 ],\n", " [0.28125 , 0.28125 , 0.28125 ],\n", " [0.25 , 0.25 , 0.25 ],\n", " [0.21875 , 0.21875 , 0.21875 ],\n", " [0.1875 , 0.1875 , 0.1875 ],\n", " [0.15625 , 0.15625 , 0.15625 ],\n", " [0.125 , 0.125 , 0.125 ],\n", " [0.09375 , 0.09375 , 0.09375 ],\n", " [0.0625 , 0.0625 , 0.0625 ],\n", " [0.03125 , 0.03125 , 0.03125 ],\n", " [0. , 0. , 0. ],\n", " [0.03846154, 0. , 0.03846154],\n", " [0.07692308, 0. , 0.07692308],\n", " [0.11538462, 0. , 0.11538462],\n", " [0.15384615, 0. , 0.15384615],\n", " [0.19230769, 0. , 0.19230769],\n", " [0.23076923, 0. , 0.23076923],\n", " [0.26923077, 0. , 0.26923077],\n", " [0.30769231, 0. , 0.30769231],\n", " [0.34615385, 0. , 0.34615385],\n", " [0.38461538, 0. , 0.38461538],\n", " [0.42307692, 0. , 0.42307692],\n", " [0.46153846, 0. , 0.46153846],\n", " [0.5 , 0. , 0.5 ],\n", " [0.5 , 0.04166667, 0.54166667],\n", " [0.5 , 0.08333333, 0.58333333],\n", " [0.5 , 0.125 , 0.625 ],\n", " [0.5 , 0.16666667, 0.66666667],\n", " [0.5 , 0.20833333, 0.70833333],\n", " [0.5 , 0.25 , 0.75 ],\n", " [0.4375 , 0.3125 , 0.75 ],\n", " [0.375 , 0.375 , 0.75 ]])" ] }, "execution_count": 82, "metadata": {}, "output_type": "execute_result" } ], "source": [ "bands_node.get_kpoints()" ] }, { "cell_type": "code", "execution_count": 83, "metadata": {}, "outputs": [ { "data": { "application/javascript": [ "/* Put everything inside the global mpl namespace */\n", "window.mpl = {};\n", "\n", "\n", "mpl.get_websocket_type = function() {\n", " if (typeof(WebSocket) !== 'undefined') {\n", " return WebSocket;\n", " } else if (typeof(MozWebSocket) !== 'undefined') {\n", " return MozWebSocket;\n", " } else {\n", " alert('Your browser does not have WebSocket support.' +\n", " 'Please try Chrome, Safari or Firefox ≥ 6. ' +\n", " 'Firefox 4 and 5 are also supported but you ' +\n", " 'have to enable WebSockets in about:config.');\n", " };\n", "}\n", "\n", "mpl.figure = function(figure_id, websocket, ondownload, parent_element) {\n", " this.id = figure_id;\n", "\n", " this.ws = websocket;\n", "\n", " this.supports_binary = (this.ws.binaryType != undefined);\n", "\n", " if (!this.supports_binary) {\n", " var warnings = document.getElementById(\"mpl-warnings\");\n", " if (warnings) {\n", " warnings.style.display = 'block';\n", " warnings.textContent = (\n", " \"This browser does not support binary websocket messages. \" +\n", " \"Performance may be slow.\");\n", " }\n", " }\n", "\n", " this.imageObj = new Image();\n", "\n", " this.context = undefined;\n", " this.message = undefined;\n", " this.canvas = undefined;\n", " this.rubberband_canvas = undefined;\n", " this.rubberband_context = undefined;\n", " this.format_dropdown = undefined;\n", "\n", " this.image_mode = 'full';\n", "\n", " this.root = $('
');\n", " this._root_extra_style(this.root)\n", " this.root.attr('style', 'display: inline-block');\n", "\n", " $(parent_element).append(this.root);\n", "\n", " this._init_header(this);\n", " this._init_canvas(this);\n", " this._init_toolbar(this);\n", "\n", " var fig = this;\n", "\n", " this.waiting = false;\n", "\n", " this.ws.onopen = function () {\n", " fig.send_message(\"supports_binary\", {value: fig.supports_binary});\n", " fig.send_message(\"send_image_mode\", {});\n", " if (mpl.ratio != 1) {\n", " fig.send_message(\"set_dpi_ratio\", {'dpi_ratio': mpl.ratio});\n", " }\n", " fig.send_message(\"refresh\", {});\n", " }\n", "\n", " this.imageObj.onload = function() {\n", " if (fig.image_mode == 'full') {\n", " // Full images could contain transparency (where diff images\n", " // almost always do), so we need to clear the canvas so that\n", " // there is no ghosting.\n", " fig.context.clearRect(0, 0, fig.canvas.width, fig.canvas.height);\n", " }\n", " fig.context.drawImage(fig.imageObj, 0, 0);\n", " };\n", "\n", " this.imageObj.onunload = function() {\n", " fig.ws.close();\n", " }\n", "\n", " this.ws.onmessage = this._make_on_message_function(this);\n", "\n", " this.ondownload = ondownload;\n", "}\n", "\n", "mpl.figure.prototype._init_header = function() {\n", " var titlebar = $(\n", " '
');\n", " var titletext = $(\n", " '
');\n", " titlebar.append(titletext)\n", " this.root.append(titlebar);\n", " this.header = titletext[0];\n", "}\n", "\n", "\n", "\n", "mpl.figure.prototype._canvas_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "\n", "mpl.figure.prototype._root_extra_style = function(canvas_div) {\n", "\n", "}\n", "\n", "mpl.figure.prototype._init_canvas = function() {\n", " var fig = this;\n", "\n", " var canvas_div = $('
');\n", "\n", " canvas_div.attr('style', 'position: relative; clear: both; outline: 0');\n", "\n", " function canvas_keyboard_event(event) {\n", " return fig.key_event(event, event['data']);\n", " }\n", "\n", " canvas_div.keydown('key_press', canvas_keyboard_event);\n", " canvas_div.keyup('key_release', canvas_keyboard_event);\n", " this.canvas_div = canvas_div\n", " this._canvas_extra_style(canvas_div)\n", " this.root.append(canvas_div);\n", "\n", " var canvas = $('');\n", " canvas.addClass('mpl-canvas');\n", " canvas.attr('style', \"left: 0; top: 0; z-index: 0; outline: 0\")\n", "\n", " this.canvas = canvas[0];\n", " this.context = canvas[0].getContext(\"2d\");\n", "\n", " var backingStore = this.context.backingStorePixelRatio ||\n", "\tthis.context.webkitBackingStorePixelRatio ||\n", "\tthis.context.mozBackingStorePixelRatio ||\n", "\tthis.context.msBackingStorePixelRatio ||\n", "\tthis.context.oBackingStorePixelRatio ||\n", "\tthis.context.backingStorePixelRatio || 1;\n", "\n", " mpl.ratio = (window.devicePixelRatio || 1) / backingStore;\n", "\n", " var rubberband = $('');\n", " rubberband.attr('style', \"position: absolute; left: 0; top: 0; z-index: 1;\")\n", "\n", " var pass_mouse_events = true;\n", "\n", " canvas_div.resizable({\n", " start: function(event, ui) {\n", " pass_mouse_events = false;\n", " },\n", " resize: function(event, ui) {\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " stop: function(event, ui) {\n", " pass_mouse_events = true;\n", " fig.request_resize(ui.size.width, ui.size.height);\n", " },\n", " });\n", "\n", " function mouse_event_fn(event) {\n", " if (pass_mouse_events)\n", " return fig.mouse_event(event, event['data']);\n", " }\n", "\n", " rubberband.mousedown('button_press', mouse_event_fn);\n", " rubberband.mouseup('button_release', mouse_event_fn);\n", " // Throttle sequential mouse events to 1 every 20ms.\n", " rubberband.mousemove('motion_notify', mouse_event_fn);\n", "\n", " rubberband.mouseenter('figure_enter', mouse_event_fn);\n", " rubberband.mouseleave('figure_leave', mouse_event_fn);\n", "\n", " canvas_div.on(\"wheel\", function (event) {\n", " event = event.originalEvent;\n", " event['data'] = 'scroll'\n", " if (event.deltaY < 0) {\n", " event.step = 1;\n", " } else {\n", " event.step = -1;\n", " }\n", " mouse_event_fn(event);\n", " });\n", "\n", " canvas_div.append(canvas);\n", " canvas_div.append(rubberband);\n", "\n", " this.rubberband = rubberband;\n", " this.rubberband_canvas = rubberband[0];\n", " this.rubberband_context = rubberband[0].getContext(\"2d\");\n", " this.rubberband_context.strokeStyle = \"#000000\";\n", "\n", " this._resize_canvas = function(width, height) {\n", " // Keep the size of the canvas, canvas container, and rubber band\n", " // canvas in synch.\n", " canvas_div.css('width', width)\n", " canvas_div.css('height', height)\n", "\n", " canvas.attr('width', width * mpl.ratio);\n", " canvas.attr('height', height * mpl.ratio);\n", " canvas.attr('style', 'width: ' + width + 'px; height: ' + height + 'px;');\n", "\n", " rubberband.attr('width', width);\n", " rubberband.attr('height', height);\n", " }\n", "\n", " // Set the figure to an initial 600x600px, this will subsequently be updated\n", " // upon first draw.\n", " this._resize_canvas(600, 600);\n", "\n", " // Disable right mouse context menu.\n", " $(this.rubberband_canvas).bind(\"contextmenu\",function(e){\n", " return false;\n", " });\n", "\n", " function set_focus () {\n", " canvas.focus();\n", " canvas_div.focus();\n", " }\n", "\n", " window.setTimeout(set_focus, 100);\n", "}\n", "\n", "mpl.figure.prototype._init_toolbar = function() {\n", " var fig = this;\n", "\n", " var nav_element = $('
')\n", " nav_element.attr('style', 'width: 100%');\n", " this.root.append(nav_element);\n", "\n", " // Define a callback function for later on.\n", " function toolbar_event(event) {\n", " return fig.toolbar_button_onclick(event['data']);\n", " }\n", " function toolbar_mouse_event(event) {\n", " return fig.toolbar_button_onmouseover(event['data']);\n", " }\n", "\n", " for(var toolbar_ind in mpl.toolbar_items) {\n", " var name = mpl.toolbar_items[toolbar_ind][0];\n", " var tooltip = mpl.toolbar_items[toolbar_ind][1];\n", " var image = mpl.toolbar_items[toolbar_ind][2];\n", " var method_name = mpl.toolbar_items[toolbar_ind][3];\n", "\n", " if (!name) {\n", " // put a spacer in here.\n", " continue;\n", " }\n", " var button = $('