Commit 2804e1d1 authored by Marco Govoni's avatar Marco Govoni
Browse files

Updated tutorial 100.

parent 1c572309
......@@ -10,4 +10,4 @@ Contents:
.. toctree::
:maxdepth: 1
westpy_100_Getting_Started
westpy_100.ipynb
%% Cell type:markdown id: tags:
# 1.1 Getting Started
This tutorial can be downloaded [link](http://greatfire.uchicago.edu/west-devel/westpy/blob/master/doc/westpy_100.ipynb).
%% Cell type:markdown id: tags:
We are going to generate an input file for the code QuantumEspresso, that computes the ground state electronic stucture for the methane molecule.
# 1 Getting Started: Ground State
%% Cell type:markdown id: tags:
We are going to generate an input file for the QuantumEspresso code or Qbox. Each code will compute the ground state electronic stucture for the methane molecule using Density Functional Theory.
%% Cell type:markdown id: tags:
## Step 1: Load westpy
%% Cell type:code id: tags:
``` python
from westpy import *
```
%%%% Output: stream
_ _ _____ _____ _____
| | | | ___/ ___|_ _|
| | | | |__ \ `--. | |_ __ _ _
| |/\| | __| `--. \ | | '_ \| | | |
\ /\ / |___/\__/ / | | |_) | |_| |
\/ \/\____/\____/ \_/ .__/ \__, |
| | __/ |
|_| |___/
WEST version : 3.1.0
Today : 2018-06-24 17:42:02.396114
Today : 2018-06-24 20:14:52.640543
%% Cell type:markdown id: tags:
## Step 1: Geometry
%% Cell type:code id: tags:
``` python
geom = Geometry()
```
%% Cell type:markdown id: tags:
Let's define a cubic cell of edge 25 Bohr.
%% Cell type:code id: tags:
``` python
geom.setCell((25,0,0),(0,25,0),(0,0,25))
```
%% Cell type:markdown id: tags:
We load the atomic positions from a XYZ file, available online.
%% Cell type:code id: tags:
``` python
geom.addAtomsFromOnlineXYZ( "http://www.west-code.org/database/gw100/xyz/CH4.xyz" )
```
%% Cell type:markdown id: tags:
We associate pseudopotential files to each species.
%% Cell type:code id: tags:
``` python
geom.addSpecies( "C", "C_ONCV_PBE-1.0.upf", "http://www.quantum-simulation.org/potentials/sg15_oncv/upf/C_ONCV_PBE-1.0.upf")
geom.addSpecies( "H", "H_ONCV_PBE-1.0.upf", "http://www.quantum-simulation.org/potentials/sg15_oncv/upf/H_ONCV_PBE-1.0.upf")
```
%% Cell type:markdown id: tags:
We can optionally download locally the pseudopotential files.
%% Cell type:code id: tags:
``` python
geom.downloadPseudopotentials()
```
%%%% Output: stream
Downloaded file: C_ONCV_PBE-1.0.upf , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/upf/C_ONCV_PBE-1.0.upf
Downloaded file: H_ONCV_PBE-1.0.upf , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/upf/H_ONCV_PBE-1.0.upf
%% Cell type:markdown id: tags:
## Step 2: Ground State
%% Cell type:markdown id: tags:
The ground state calculation is defined by the geometry, a choice of the exchange-correlation functional, and by setting an energy cutoff for the wavefunctions.
%% Cell type:code id: tags:
``` python
gs = GroundState(geom,xc="PBE",ecut=40.0)
```
%% Cell type:markdown id: tags:
We are now able to generate the input file for QuantumEspresso.
%% Cell type:code id: tags:
``` python
gs.generateInputPW()
```
%%%% Output: stream
Generated file: pw.in
%% Cell type:markdown id: tags:
We can inspect the file pw.in
%% Cell type:code id: tags:
``` python
!cat pw.in
with open("pw.in","r") as file :
data = file.read()
print(data)
```
%%%% Output: stream
&CONTROL
calculation = 'scf'
restart_mode = 'from_scratch'
pseudo_dir = './'
outdir = './'
prefix = 'calc'
wf_collect = .TRUE.
/
&SYSTEM
ibrav = 0
nat = 5
ntyp = 2
ecutwfc = 40.0
nbnd = 8
input_dft = 'PBE'
nosym = .TRUE.
noinv = .TRUE.
/
&ELECTRONS
diago_full_acc = .TRUE.
conv_tol = 1.d-8
/
ATOMIC_SPECIES
C 12.011 C_ONCV_PBE-1.0.upf
H 1.008 H_ONCV_PBE-1.0.upf
ATOMIC_POSITIONS {bohr}
C 0.0 0.0 0.0
H 1.185992116575257 -1.185803143962673 1.185992116575257
H -1.185992116575257 1.185992116575257 1.185992116575257
H -1.185992116575257 -1.185992116575257 -1.185992116575257
H 1.185992116575257 1.185992116575257 -1.185992116575257
K_POINTS {gamma}
CELL_PARAMETERS {bohr}
25.0 0.0 0.0
0.0 25.0 0.0
0.0 0.0 25.0
%% Cell type:markdown id: tags:
We can optionally also download the pseudopotentials files.
%% Cell type:code id: tags:
``` python
gs.downloadPseudopotentials()
```
%%%% Output: stream
Downloaded file: C_ONCV_PBE-1.0.upf , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/upf/C_ONCV_PBE-1.0.upf
Downloaded file: H_ONCV_PBE-1.0.upf , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/upf/H_ONCV_PBE-1.0.upf
%% Cell type:markdown id: tags:
## Step 3: Ground State with Qbox
%% Cell type:markdown id: tags:
To generate the input for Qbox we can simply update Species to use the xml formats.
%% Cell type:code id: tags:
``` python
gs.updateSpecies("C", "C_ONCV_PBE-1.0.xml", "http://www.quantum-simulation.org/potentials/sg15_oncv/xml/C_ONCV_PBE-1.0.xml")
gs.updateSpecies("H", "H_ONCV_PBE-1.0.xml", "http://www.quantum-simulation.org/potentials/sg15_oncv/xml/H_ONCV_PBE-1.0.xml")
```
%% Cell type:markdown id: tags:
We are now able to generate the input file for QuantumEspresso.
%% Cell type:code id: tags:
``` python
gs.generateInputQbox()
```
%%%% Output: stream
Generated file: qbox.in
%% Cell type:markdown id: tags:
We can inspect the file qbox.in
%% Cell type:code id: tags:
``` python
with open("qbox.in","r") as file :
data = file.read()
print(data)
```
%%%% Output: stream
set cell 25.0 0.0 0.0 0.0 25.0 0.0 0.0 0.0 25.0
species Carbon C_ONCV_PBE-1.0.xml
species Hydrogen H_ONCV_PBE-1.0.xml
atom C1 Carbon 0.0 0.0 0.0
atom H2 Hydrogen 1.185992116575257 -1.185803143962673 1.185992116575257
atom H3 Hydrogen -1.185992116575257 1.185992116575257 1.185992116575257
atom H4 Hydrogen -1.185992116575257 -1.185992116575257 -1.185992116575257
atom H5 Hydrogen 1.185992116575257 1.185992116575257 -1.185992116575257
set ecut 40.0
set wf_dyn JD
set xc PBE
set scf_tol 1.e-8
randomize_wf
run -atomic_density 0 100 5
save gs.xml
%% Cell type:markdown id: tags:
We can optionally also download the pseudopotentials files.
%% Cell type:code id: tags:
``` python
gs.downloadPseudopotentials()
```
%%%% Output: stream
Downloaded file: C_ONCV_PBE-1.0.xml , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/xml/C_ONCV_PBE-1.0.xml
Downloaded file: H_ONCV_PBE-1.0.xml , from url: http://www.quantum-simulation.org/potentials/sg15_oncv/xml/H_ONCV_PBE-1.0.xml
%% Cell type:code id: tags:
``` python
```
......
......@@ -58,7 +58,7 @@ class Geometry(object) :
:param fname: file name
:type fname: string
:param url: url
:type url: units
:type url: string
:Example:
......@@ -68,16 +68,12 @@ class Geometry(object) :
.. note:: You can use this method to add either upf or xml pseudopotentials. However it is forbidded to mix them.
"""
this_pseudo_format = None
this_pseudo_format = None
if( fname.endswith("upf") or fname.endswith("UPF")) :
this_pseudo_format = "upf"
if( fname.endswith("xml") or fname.endswith("XML")) :
this_pseudo_format = "xml"
assert( this_pseudo_format in ["upf","xml"] )
if self.pseudoFormat is None :
self.pseudoFormat = this_pseudo_format
else :
assert( self.pseudoFormat == this_pseudo_format )
from mendeleev import element
el = element(symbol)
self.species[symbol] = {}
......@@ -87,8 +83,22 @@ class Geometry(object) :
self.species[symbol]["atomic_number"] = el.atomic_number
self.species[symbol]["name"] = el.name
self.species[symbol]["mass"] = el.mass
self.species[symbol]["format"] = this_pseudo_format
self.__updatePseudoFormat()
self.isSet["species"] = True
#
def __updatePseudoFormat(self) :
"""pseudo format is either upf, xml or mixed.
"""
f = []
for key in self.species.keys() :
f.append(self.species[key]["format"])
self.pseudoFormat = 'mixed'
if( all(form == 'upf' for form in f) ) :
self.pseudoFormat = 'upf'
if( all(form == 'xml' for form in f) ) :
self.pseudoFormat = 'xml'
#
def setCell(self, a1=(0, 0, 0), a2=(0, 0, 0), a3=(0, 0, 0), units=Bohr ) :
"""Sets cell, given the three vectors :math:`a_1`, :math:`a_2`, :math:`a_3`.
......
......@@ -111,70 +111,74 @@ class GroundState :
>>> gs.generateInputPW("pw.in")
"""
#
with open(fname, "w") as file :
file.write("&CONTROL\n")
file.write("calculation = 'scf'\n")
file.write("restart_mode = 'from_scratch'\n")
file.write("pseudo_dir = './'\n")
file.write("outdir = './'\n")
file.write("prefix = 'calc'\n")
file.write("wf_collect = .TRUE.\n")
file.write("/\n")
file.write("&SYSTEM\n")
file.write("ibrav = 0\n")
file.write("nat = " + str(self.geom.getNumberOfAtoms()) + "\n" )
file.write("ntyp = " + str(self.geom.getNumberOfSpecies()) + "\n" )
file.write("ecutwfc = " + str(self.ecut) + "\n" )
file.write("nbnd = " + str(self.geom.getNumberOfElectrons() + self.nempty) + "\n" )
file.write("input_dft = '" + str(self.xc) +"'\n" )
file.write("nosym = .TRUE.\n" )
file.write("noinv = .TRUE.\n" )
if( "nspin" in self.spin.keys() ) :
if( self.spin["nspin"] == 2 ) :
file.write("nspin = 2\n" )
file.write("tot_magnetization = " + str(self.spin["tot_magnetization"]) + "\n" )
if( self.spin["nspin"] == 4 ) :
file.write("noncolin = .TRUE.\n" )
from westpy import logical2str
file.write("lspinorb = " + logical2str(self.spin["lspinorb"]) +"\n" )
if( self.isolated ) :
file.write("assume_isolated = 'mp'\n")
file.write("/\n")
if( self.geom.pseudoFormat in ["upf"]) :
#
file.write("&ELECTRONS\n")
file.write("diago_full_acc = .TRUE.\n")
file.write("conv_tol = 1.d-8\n")
file.write("/\n")
#
file.write("ATOMIC_SPECIES\n")
sp = []
for atom in self.geom.atoms :
if( atom.symbol not in sp ) :
sp.append(atom.symbol)
file.write(atom.symbol + " " + str(self.geom.species[atom.symbol]["mass"]) + " " + self.geom.species[atom.symbol]["fname"] + "\n")
#
file.write("ATOMIC_POSITIONS {bohr}\n")
for atom in self.geom.atoms :
file.write(atom.symbol + " " + str(atom.position[0]) + " " + str(atom.position[1]) + " " + str(atom.position[2]) + "\n")
#
if ( self.kmesh in ["gamma"] ) :
file.write("K_POINTS {gamma}\n")
else :
file.write("K_POINTS {automatic}\n")
file.write(str(self.kmesh[0]) + " " + str(self.kmesh[1]) + " " + str(self.kmesh[2]) + " 0 0 0\n")
#
file.write("CELL_PARAMETERS {bohr}\n")
cell = self.geom.cell
a1 = cell[0]
a2 = cell[1]
a3 = cell[2]
file.write(str(a1[0]) + " " + str(a1[1]) + " " + str(a1[2]) + "\n" )
file.write(str(a2[0]) + " " + str(a2[1]) + " " + str(a2[2]) + "\n" )
file.write(str(a3[0]) + " " + str(a3[1]) + " " + str(a3[2]) + "\n" )
#
print("")
print("Generated file: ", fname )
#
with open(fname, "w") as file :
file.write("&CONTROL\n")
file.write("calculation = 'scf'\n")
file.write("restart_mode = 'from_scratch'\n")
file.write("pseudo_dir = './'\n")
file.write("outdir = './'\n")
file.write("prefix = 'calc'\n")
file.write("wf_collect = .TRUE.\n")
file.write("/\n")
file.write("&SYSTEM\n")
file.write("ibrav = 0\n")
file.write("nat = " + str(self.geom.getNumberOfAtoms()) + "\n" )
file.write("ntyp = " + str(self.geom.getNumberOfSpecies()) + "\n" )
file.write("ecutwfc = " + str(self.ecut) + "\n" )
file.write("nbnd = " + str(self.geom.getNumberOfElectrons() + self.nempty) + "\n" )
file.write("input_dft = '" + str(self.xc) +"'\n" )
file.write("nosym = .TRUE.\n" )
file.write("noinv = .TRUE.\n" )
if( "nspin" in self.spin.keys() ) :
if( self.spin["nspin"] == 2 ) :
file.write("nspin = 2\n" )
file.write("tot_magnetization = " + str(self.spin["tot_magnetization"]) + "\n" )
if( self.spin["nspin"] == 4 ) :
file.write("noncolin = .TRUE.\n" )
from westpy import logical2str
file.write("lspinorb = " + logical2str(self.spin["lspinorb"]) +"\n" )
if( self.isolated ) :
file.write("assume_isolated = 'mp'\n")
file.write("/\n")
#
file.write("&ELECTRONS\n")
file.write("diago_full_acc = .TRUE.\n")
file.write("conv_tol = 1.d-8\n")
file.write("/\n")
#
file.write("ATOMIC_SPECIES\n")
sp = []
for atom in self.geom.atoms :
if( atom.symbol not in sp ) :
sp.append(atom.symbol)
file.write(atom.symbol + " " + str(self.geom.species[atom.symbol]["mass"]) + " " + self.geom.species[atom.symbol]["fname"] + "\n")
#
file.write("ATOMIC_POSITIONS {bohr}\n")
for atom in self.geom.atoms :
file.write(atom.symbol + " " + str(atom.position[0]) + " " + str(atom.position[1]) + " " + str(atom.position[2]) + "\n")
#
if ( self.kmesh in ["gamma"] ) :
file.write("K_POINTS {gamma}\n")
else :
file.write("K_POINTS {automatic}\n")
file.write(str(self.kmesh[0]) + " " + str(self.kmesh[1]) + " " + str(self.kmesh[2]) + " 0 0 0\n")
#
file.write("CELL_PARAMETERS {bohr}\n")
cell = self.geom.cell
a1 = cell[0]
a2 = cell[1]
a3 = cell[2]
file.write(str(a1[0]) + " " + str(a1[1]) + " " + str(a1[2]) + "\n" )
file.write(str(a2[0]) + " " + str(a2[1]) + " " + str(a2[2]) + "\n" )
file.write(str(a3[0]) + " " + str(a3[1]) + " " + str(a3[2]) + "\n" )
#
print("")
print("Generated file: ", fname )
#
else :
print("Cannot generate input for QuantumEspresso, pseudo are not upf.")
#
def generateInputQbox(self,fname="qbox.in") :
"""Generates input file for qbox. Valid only for Qbox calculations.
......@@ -187,37 +191,70 @@ class GroundState :
>>> gs.generateInputQbox("qbox.in")
"""
#
with open(fname, "w") as file :
# cell
cell = self.geom.cell
a1 = cell[0]
a2 = cell[1]
a3 = cell[2]
file.write("set cell " + str(a1[0]) + " " + str(a1[1]) + " " + str(a1[2]) + " " + str(a2[0]) + " " + str(a2[1]) + " " + str(a2[2]) + " " + str(a3[0]) + " " + str(a3[1]) + " " + str(a3[2]) + "\n" )
# species
sp = []
for atom in self.geom.atoms :
if( atom.symbol not in sp ) :
sp.append(atom.symbol)
file.write("species " + self.geom.species[atom.symbol]["name"] + " " + self.geom.species[atom.symbol]["fname"] + "\n")
# atom
i = 0
for atom in self.geom.atoms :
i+=1
file.write("atom " + atom.symbol+str(i) + " " + self.geom.species[atom.symbol]["name"] + " " + str(atom.position[0]) + " " + str(atom.position[1]) + " " + str(atom.position[2]) + "\n")
#
file.write("set ecut " + str(self.ecut) +"\n")
if( self.nempty > 0 ) :
file.write("set nempty " + self.nempty + "\n")
file.write("set wf_dyn JD\n")
file.write("set xc " + self.xc + "\n")
file.write("set scf_tol 1.e-8\n")
if( "nspin" in self.spin.keys() or self.isolated or self.kmesh not in ["gamma"] ) :
print("ERR: non supported")
file.write("randomize_wf\n")
file.write("run -atomic_density 0 100 5\n")
file.write("save gs.xml\n")
if( self.geom.pseudoFormat in ["xml"] ) :
#
print("")
print("Generated file: ", fname )
#
with open(fname, "w") as file :
# cell
cell = self.geom.cell
a1 = cell[0]
a2 = cell[1]
a3 = cell[2]
file.write("set cell " + str(a1[0]) + " " + str(a1[1]) + " " + str(a1[2]) + " " + str(a2[0]) + " " + str(a2[1]) + " " + str(a2[2]) + " " + str(a3[0]) + " " + str(a3[1]) + " " + str(a3[2]) + "\n" )
# species
sp = []
for atom in self.geom.atoms :
if( atom.symbol not in sp ) :
sp.append(atom.symbol)
file.write("species " + self.geom.species[atom.symbol]["name"] + " " + self.geom.species[atom.symbol]["fname"] + "\n")
# atom
i = 0
for atom in self.geom.atoms :
i+=1
file.write("atom " + atom.symbol+str(i) + " " + self.geom.species[atom.symbol]["name"] + " " + str(atom.position[0]) + " " + str(atom.position[1]) + " " + str(atom.position[2]) + "\n")
#
file.write("set ecut " + str(self.ecut) +"\n")
if( self.nempty > 0 ) :
file.write("set nempty " + self.nempty + "\n")
file.write("set wf_dyn JD\n")
file.write("set xc " + self.xc + "\n")
file.write("set scf_tol 1.e-8\n")
if( "nspin" in self.spin.keys() or self.isolated or self.kmesh not in ["gamma"] ) :
print("ERR: non supported")
file.write("randomize_wf\n")
file.write("run -atomic_density 0 100 5\n")
file.write("save gs.xml\n")
#
print("")
print("Generated file: ", fname )
#
else :
print("Cannot generate input for Qbox, pseudo are not xml.")
#
def downloadPseudopotentials(self) :
"""Download Pseudopotentials.
:Example:
>>> gs.downloadPseudopotentials()
.. note:: Pseudopotential files will be downloaded in the current directory.
"""
self.geom.downloadPseudopotentials()
#
def updateSpecies(self,symbol,fname,url) :
"""Update a species.
:param symbol: chemical symbol
:type symbol: string
:param fname: file name
:type fname: string
:param url: url
:type url: string
:Example:
>>> geom.addSpecies( "Si", "Si_ONCV_PBE-1.1.upf", "http://www.quantum-simulation.org/potentials/sg15_oncv/upf/Si_ONCV_PBE-1.1.upf" )
.. note:: You can use this method to add either upf or xml pseudopotentials. However it is forbidded to mix them.
"""
self.geom.addSpecies(symbol,fname,url)
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment