Tutorial: Quantum ESPRESSO wrapper

In this tutorial we will go through a simple example of how to use the wrapper for the Quantum Espresso simulation engine. You can find the wrapper here.

Background

This is an example of a slightly different design based upon the input-output functionality of certain simulation engines such as Quantum Espresso and Gromacs.

Let’s get hands-on

Installation

To run the local installation of Quantum Espresso, simply run ./install_engine.sh. This should check for the prerequisites and compile the code for Quantum Espresso for you.

If the script runs into an error finding openmpi-bin or something like that, try running apt-get update and try again. Once the installation has completed, try running pw.x to see if the installation has succeeded. If this does not work, then try adding export PATH=$PATH:/home/username/qe-6.1/bin/ at the end of .bashrc located at your home folder.

Once you have verified that pw.x works, install the ontology via pico install ontology.simlammps.yml, and make sure to run python3 setup.py located in the root of the quantum espresso wrapper folder.

That should be all needed to use Quantum Espresso!

Simple example

This is an adaptation of quantum-espresso-wrapper/examples/Simple.py. As usual, we need to import the necessary components:

[1]:
import numpy as np

from osp.core.namespaces import QE
from osp.core.utils import pretty_print
from osp.wrappers.quantumespresso.qe_session import qeSession

Next, we create simulation and its K points, which determine at what points it samples the cell

[2]:
sim = QE.Simulation()
k = QE.K_POINTS(vector = (7, 7, 7), unit = "")

Next, we create a cell, the element Silicon, a pseudopotential, an atom and the cell parameters. Note that the pseudopotential files should ALWAYS be located inside of a folder named $PSEUDO_DIR inside of wherever you are running the simulation.

[3]:
SiCell = QE.Cell()
Si = QE.Element(name = "Si")
SiPseudo = QE.PSEUDOPOTENTIAL(name = "Si.pbe-n-kjpaw_psl.1.0.0.UPF")
Si1 = QE.Atom()
SiParams = QE.CellParams()
celldm1 = QE.Celldm1(value = 5.43070, unit = "au")

Next, we connect these all to each other using the add method.

[4]:
Si.add(SiPseudo, Si1)
Si.add(QE.Mass(value = 28.085, unit = "amu"))
SiCell.add(Si1, SiParams)
Si1.add(QE.Position(vector = (0, 0, 0), unit = ""))
SiCell.add(celldm1)
[4]:
<qe.Celldm1: be8f3915-3eb7-4221-a441-345eda51832b,  CoreSession: @0x7feae9717370>

We specify the cell parameters:

[5]:
SiParams.add(QE.CellParameterX(vector = (0.5, 0.5, 0), unit = ""),
             QE.CellParameterY(vector = (0.5, 0, 0.5), unit = ""),
             QE.CellParameterZ(vector = (0, 0.5, 0.5), unit = ""))
[5]:
[<qe.CellParameterX: 0ebdeed9-1d8a-498d-94c9-bafccb05d652,  CoreSession: @0x7feae9717370>,
 <qe.CellParameterY: fea8789c-8c07-49f9-9971-8d42bdd6ba3f,  CoreSession: @0x7feae9717370>,
 <qe.CellParameterZ: 1474d106-4204-428d-827b-2d5e2cb4af51,  CoreSession: @0x7feae9717370>]

And then we add everything created so far to the simulation:

[6]:
sim.add(SiCell)
sim.add(Si)
sim.add(k)
[6]:
<qe.K_POINTS: 6847a5f0-8d20-4f73-9eb3-043e78053182,  CoreSession: @0x7feae9717370>

While we’re add it, let’s add some variables to the simulation which we can check to see if they have been updated. They will not be taken into account when simulating, so they’re there for control purposes.

[7]:
sim.add(QE.Pressure(value = 100, unit = "kbar"))
sim.add(QE.StressTensor(tensor2 = np.zeros((3, 3)), unit = "kbar"))
[7]:
<qe.StressTensor: 2f302f8b-89b8-4d7a-a2a7-4f6e19737f00,  CoreSession: @0x7feae9717370>

Let’s check out what this simulation looks like now with the pretty_print function:

[8]:
pretty_print(sim)
- Cuds object:
  uuid: 903145ad-50e3-46fc-9d28-1aa1ec364e8a
  type: qe.Simulation
  superclasses: cuba.Class, cuba.Entity, qe.Simulation
  description:
    All components of the simulation that are needed to run the model

   |_Relationship qe.HAS_PART:
     -  qe.Cell cuds object:
     .  uuid: 67a0fcb4-4977-49df-9bcb-13bca17b2763
     .   |_Relationship qe.HAS_PART:
     .     -  qe.Atom cuds object:
     .     .  uuid: 1bad1c25-609a-4bc0-8c65-3c0167cfdbe2
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.Position cuds object:
     .     .        uuid: c70afbb3-0012-488d-8059-b44d775c6b23
     .     .        vector: [0. 0. 0.]
     .     .        unit:
     .     -  qe.CellParams cuds object:
     .     .  uuid: f444899a-e850-4ab2-b79e-c91026523eb3
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.CellParameterX cuds object:
     .     .     .  uuid: 0ebdeed9-1d8a-498d-94c9-bafccb05d652
     .     .     .  vector: [0.5 0.5 0. ]
     .     .     .  unit:
     .     .     -  qe.CellParameterY cuds object:
     .     .     .  uuid: fea8789c-8c07-49f9-9971-8d42bdd6ba3f
     .     .     .  vector: [0.5 0.  0.5]
     .     .     .  unit:
     .     .     -  qe.CellParameterZ cuds object:
     .     .        uuid: 1474d106-4204-428d-827b-2d5e2cb4af51
     .     .        vector: [0.  0.5 0.5]
     .     .        unit:
     .     -  qe.Celldm1 cuds object:
     .        uuid: be8f3915-3eb7-4221-a441-345eda51832b
     .        unit: au
     .        value: 5.4307
     -  qe.Element cuds object named <Si>:
     .  uuid: 8628ceb7-1c02-4014-95a4-d9450aab4753
     .   |_Relationship qe.HAS_PART:
     .     -  qe.Atom cuds object:
     .     .  uuid: 1bad1c25-609a-4bc0-8c65-3c0167cfdbe2
     .     .  (already printed)
     .     -  qe.Mass cuds object:
     .     .  uuid: 1aee515a-4e12-40e6-bbd6-23bf5c95fe84
     .     .  unit: amu
     .     .  value: 28.085
     .     -  qe.PSEUDOPOTENTIAL cuds object named <Si.pbe-n-kjpaw_psl.1.0.0.UPF>:
     .        uuid: cb27bcb9-27c6-48a9-8f1e-8977b16567c5
     -  qe.K_POINTS cuds object:
     .  uuid: 6847a5f0-8d20-4f73-9eb3-043e78053182
     .  vector: [7. 7. 7.]
     .  unit:
     -  qe.Pressure cuds object:
     .  uuid: d281d93d-fd10-41fd-868c-0cda3b510431
     .  unit: kbar
     .  value: 100.0
     -  qe.StressTensor cuds object:
        uuid: 2f302f8b-89b8-4d7a-a2a7-4f6e19737f00
        unit: kbar
        tensor2: [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

Now, it’s time to get the simulation running:

[12]:
session = qeSession()
quantum_espresso_wrapper = QE.QEWrapper(session = session)
quantum_espresso_wrapper.add(sim)
print("Running calculation...")

quantum_espresso_wrapper.session._run(simulation = sim, prefix = "si", command_type = "pw.x", calculation_type = "scf", root = "", CONTROL = {'pseudo_dir': "'.'"})
Running calculation...
/mnt/c/iwm/docs/si.pwscf.in
pw.x -i /mnt/c/iwm/docs/si.pwscf.in > /mnt/c/iwm/docs/si.pwscf.out

Now let’s check the results of our calculation:

[10]:
pretty_print(sim)
- Cuds object:
  uuid: 903145ad-50e3-46fc-9d28-1aa1ec364e8a
  type: qe.Simulation
  superclasses: cuba.Class, cuba.Entity, qe.Simulation
  description:
    All components of the simulation that are needed to run the model

   |_Relationship qe.HAS_PART:
     -  qe.Cell cuds object:
     .  uuid: 67a0fcb4-4977-49df-9bcb-13bca17b2763
     .   |_Relationship qe.HAS_PART:
     .     -  qe.Atom cuds object:
     .     .  uuid: 1bad1c25-609a-4bc0-8c65-3c0167cfdbe2
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.Position cuds object:
     .     .        uuid: c70afbb3-0012-488d-8059-b44d775c6b23
     .     .        vector: [0. 0. 0.]
     .     .        unit:
     .     -  qe.CellParams cuds object:
     .     .  uuid: f444899a-e850-4ab2-b79e-c91026523eb3
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.CellParameterX cuds object:
     .     .     .  uuid: 0ebdeed9-1d8a-498d-94c9-bafccb05d652
     .     .     .  vector: [0.5 0.5 0. ]
     .     .     .  unit:
     .     .     -  qe.CellParameterY cuds object:
     .     .     .  uuid: fea8789c-8c07-49f9-9971-8d42bdd6ba3f
     .     .     .  vector: [0.5 0.  0.5]
     .     .     .  unit:
     .     .     -  qe.CellParameterZ cuds object:
     .     .        uuid: 1474d106-4204-428d-827b-2d5e2cb4af51
     .     .        vector: [0.  0.5 0.5]
     .     .        unit:
     .     -  qe.Celldm1 cuds object:
     .        uuid: be8f3915-3eb7-4221-a441-345eda51832b
     .        unit: au
     .        value: 5.4307
     -  qe.Element cuds object named <Si>:
     .  uuid: 8628ceb7-1c02-4014-95a4-d9450aab4753
     .   |_Relationship qe.HAS_PART:
     .     -  qe.Atom cuds object:
     .     .  uuid: 1bad1c25-609a-4bc0-8c65-3c0167cfdbe2
     .     .  (already printed)
     .     -  qe.Mass cuds object:
     .     .  uuid: 1aee515a-4e12-40e6-bbd6-23bf5c95fe84
     .     .  unit: amu
     .     .  value: 28.085
     .     -  qe.PSEUDOPOTENTIAL cuds object named <Si.pbe-n-kjpaw_psl.1.0.0.UPF>:
     .        uuid: cb27bcb9-27c6-48a9-8f1e-8977b16567c5
     -  qe.K_POINTS cuds object:
     .  uuid: 6847a5f0-8d20-4f73-9eb3-043e78053182
     .  vector: [7. 7. 7.]
     .  unit:
     -  qe.Pressure cuds object:
     .  uuid: d281d93d-fd10-41fd-868c-0cda3b510431
     .  unit: kbar
     .  value: 100.0
     -  qe.PwOut cuds object:
     .  uuid: 15c6637e-9124-44dd-a1d3-f225203c1bfc
     .  path: /mnt/c/iwm/docs/si.pwscf.out
     -  qe.StressTensor cuds object:
        uuid: 2f302f8b-89b8-4d7a-a2a7-4f6e19737f00
        unit: kbar
        tensor2: [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

As you can see, the original part of the cuds tree is still there, with everything mostly the same. The new parts are:

  • The qe.PwOut cuds object. This is the output file of the simulation, in case there is something that the wrapper does not parse but that you would still like to see.

  • The qe.TotalEnergy cuds object. This was parsed from the qe.PwOut file itself.

  • The qe.Force cuds object. This represents the force exerted on the atom(s).

The updated parts are:

  • The qe.Pressure cuds object, having changed in value from 100 kbar to 5723.64 kbar.

  • The qe.StressTensor cuds object, which is no longer zero.

Let’s see if we can do better and calculate some bands structures:

[21]:
quantum_espresso_wrapper.session._run(prefix = "si", command_type = "pw.x", calculation_type = "bands")
quantum_espresso_wrapper.session._run(prefix = "si", command_type = "bands.x", calculation_type = "")
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-51324d6941c1> in <module>
----> 1 quantum_espresso_wrapper.session._run(prefix = "si", command_type = "pw.x", calculation_type = "bands")
      2 quantum_espresso_wrapper.session._run(prefix = "si", command_type = "bands.x", calculation_type = "")

TypeError: _run() missing 1 required positional argument: 'simulation'

Although the cuds structure won’t have changed much by this, the data is there in the folder.

Now let’s try to relax this cell. While it isn’t a real cell, we can still perform the calculations to relax it to know what the movement of the atoms would be like if it were a real cell (warning, perform vc-relax type calculations with caution. These examples are designed to be lightweight and non-indicative of real-world applications).

[22]:
quantum_espresso_wrapper.session._run(simulation = sim, prefix = "si", command_type = "pw.x", calculation_type = "relax", IONS = {'ion_dynamics': "'bfgs'"})
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-8a4fa9c53f25> in <module>
----> 1 quantum_espresso_wrapper.session._run(prefix = "si", command_type = "pw.x", calculation_type = "relax", IONS = {'ion_dynamics': "'bfgs'"})

TypeError: _run() missing 1 required positional argument: 'simulation'
[23]:
pretty_print(sim)
- Cuds object:
  uuid: 90361daa-6905-4566-979e-11b3b0dd4e85
  type: qe.Simulation
  superclasses: cuba.Class, cuba.Entity, qe.Simulation
  description:
    All components of the simulation that are needed to run the model

   |_Relationship qe.HAS_PART:
     -  qe.Cell cuds object:
     .  uuid: f7548873-28e9-4d76-86da-6fddb687d29e
     .   |_Relationship qe.HAS_PART:
     .     -  qe.Atom cuds object:
     .     .  uuid: 53114a1f-ebbb-4e4b-a115-080925d9eaa8
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.Position cuds object:
     .     .        uuid: 48d4483b-7c72-4454-8041-581dc73fd216
     .     .        vector: [0. 0. 0.]
     .     .        unit:
     .     -  qe.CellParams cuds object:
     .     .  uuid: 9d61e990-2509-474b-935e-618ca11bb40d
     .     .   |_Relationship qe.HAS_PART:
     .     .     -  qe.CellParameterX cuds object:
     .     .     .  uuid: f2655054-efa7-4b39-9f0a-cf6453be68ec
     .     .     .  vector: [0.5 0.5 0. ]
     .     .     .  unit:
     .     .     -  qe.CellParameterY cuds object:
     .     .     .  uuid: 55647575-ea8f-4ef7-aee8-2a3333a4ec71
     .     .     .  vector: [0.5 0.  0.5]
     .     .     .  unit:
     .     .     -  qe.CellParameterZ cuds object:
     .     .        uuid: 92be9c63-ee80-46d9-8853-ccb562e94a5b
     .     .        vector: [0.  0.5 0.5]
     .     .        unit:
     .     -  qe.Celldm1 cuds object:
     .     .  uuid: db776c65-9d2e-448e-bc55-5fe0f9c7ee75
     .     .  unit: au
     .     .  value: 5.4307
     .     -  qe.Element cuds object named <Si>:
     .        uuid: 14dacecb-023c-4ace-9e83-35b0ecaa1032
     .         |_Relationship qe.HAS_PART:
     .           -  qe.Atom cuds object:
     .           .  uuid: 53114a1f-ebbb-4e4b-a115-080925d9eaa8
     .           .  (already printed)
     .           -  qe.Atom cuds object:
     .           .  uuid: c2094a19-8769-4298-a50a-be1f8befe5bf
     .           .   |_Relationship qe.HAS_PART:
     .           .     -  qe.Position cuds object:
     .           .        uuid: 4087ce47-16f0-4449-b8c4-4577e6d265e2
     .           .        vector: [0.25 0.25 0.26]
     .           .        unit:
     .           -  qe.Mass cuds object:
     .           .  uuid: 5d57a768-d315-4f91-84a8-fcfad9aae382
     .           .  unit: amu
     .           .  value: 28.085
     .           -  qe.PSEUDOPOTENTIAL cuds object named <Si.pbe-n-kjpaw_psl.1.0.0.UPF>:
     .              uuid: ab064983-5cc9-418e-a9e7-3357c04388f5
     -  qe.Element cuds object named <Si>:
     .  uuid: 14dacecb-023c-4ace-9e83-35b0ecaa1032
     .  (already printed)
     -  qe.K_POINTS cuds object:
     .  uuid: 38385f3b-128c-491f-91f4-44de15055d56
     .  vector: [7. 7. 7.]
     .  unit:
     -  qe.Pressure cuds object:
     .  uuid: 57f47fa8-4588-488f-8c89-fa8a0f37f567
     .  unit: kbar
     .  value: 100.0
     -  qe.Pressure cuds object:
     .  uuid: beac6977-01cf-4b4d-b89b-1b4d4eecf5c0
     .  unit: kbar
     .  value: 100.0
     -  qe.PwOut cuds object:
     .  uuid: 7890c86c-9f6f-42b3-a02c-cd57f5307c75
     .  path: si.pwscf.out
     -  qe.PwOut cuds object:
     .  uuid: 5c7e31f9-6e55-4ddf-af62-5a3e58811464
     .  path: si.pwscf.out
     -  qe.StressTensor cuds object:
     .  uuid: 16b33d51-0f6d-4451-a919-da494a13082f
     .  unit: kbar
     .  tensor2: [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]
     -  qe.StressTensor cuds object:
        uuid: 590ad64e-d110-4711-90c6-0986bb53dafc
        unit: kbar
        tensor2: [[0. 0. 0.]
 [0. 0. 0.]
 [0. 0. 0.]]

In this example, the position hasn’t changed. So let’s spice things up a little bit and add another atom, and then relax:

[24]:
Si2 = QE.Atom()
Si2.add(QE.Position(vector = (0.25, 0.25, 0.26), unit = ""))
SiCell.add(Si)
Si.add(Si2)
pretty_print(sim)
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-24-6957eba14ddb> in <module>
      1 Si2 = QE.Atom()
      2 Si2.add(QE.Position(vector = (0.25, 0.25, 0.26), unit = ""))
----> 3 SiCell.add(Si)
      4 Si.add(Si2)
      5 pretty_print(sim)

/mnt/c/IWM/osp-core-3.4.0-dev/osp/core/cuds.py in add(self, rel, *args)
    161             if rel in self._neighbors and arg.uid in self._neighbors[rel]:
    162                 message = '{!r} is already in the container'
--> 163                 raise ValueError(message.format(arg))
    164             if self.session != arg.session:
    165                 arg = self._recursive_store(arg, next(old_objects))

ValueError: <qe.Element: 14dacecb-023c-4ace-9e83-35b0ecaa1032,  CoreSession: @0x7f3d2d38bfa0> is already in the container
[25]:
quantum_espresso_wrapper.session._run(simulation = sim, prefix = "si", command_type = "pw.x", calculation_type = "relax", IONS = {'ion_dynamics': "'bfgs'"})
pretty_print(sim)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-25-8eda2c089407> in <module>
----> 1 quantum_espresso_wrapper.session._run(prefix = "si", command_type = "pw.x", calculation_type = "relax", IONS = {'ion_dynamics': "'bfgs'"})
      2 pretty_print(sim)

TypeError: _run() missing 1 required positional argument: 'simulation'