mirror of https://github.com/abinit/abipy.git
Move lessons to abitutorials
This commit is contained in:
parent
515cae639f
commit
d069348ec5
|
@ -34,7 +34,7 @@ Check out the list of plotting scripts available in our
|
|||
To learn more about the integration between jupyter and AbiPy, visit our collection of `notebooks
|
||||
<http://nbviewer.ipython.org/github/abinit/abipy/blob/master/abipy/examples/notebooks/index.ipynb>`_
|
||||
and the
|
||||
`AbiPy lessons <http://nbviewer.ipython.org/github/abinit/abipy/blob/master/abipy/examples/notebooks/lessons/index.ipynb>`_.
|
||||
`AbiPy lessons <https://nbviewer.jupyter.org/github/abinit/abitutorials/tree/master/abitutorials/index.ipynb>`_.
|
||||
|
||||
AbiPy supports both Python 2.7 as well as Python >= 3.4.
|
||||
Python 2.7 is more intensively tested than py3k especially at the level of workflows
|
||||
|
|
|
@ -1,41 +0,0 @@
|
|||
"""Directory with abipy + abinit tutorials."""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import os
|
||||
|
||||
from importlib import import_module
|
||||
|
||||
|
||||
def help():
|
||||
"""List the available tutorials with a brief description."""
|
||||
docs = [m.__doc__ for mod in get_mods()]
|
||||
return "\n".join(docs)
|
||||
|
||||
|
||||
def get_mods():
|
||||
mods = []
|
||||
dirpath = os.path.abspath(os.path.dirname(__file__))
|
||||
for pyfile in os.listdir(dirpath):
|
||||
if not (pyfile.startswith("lesson") and pyfile.endswith(".py")): continue
|
||||
path = os.path.join(os.path.dirname(dirpath), pyfile)
|
||||
mods.append(import_module(pyfile.replace(".py", "")))
|
||||
|
||||
return mods
|
||||
|
||||
|
||||
def generate_manfiles():
|
||||
"""Generate the man files from the lesson scripts."""
|
||||
for mod in get_mods():
|
||||
try:
|
||||
lesson = mod.Lesson()
|
||||
|
||||
except AttributeError:
|
||||
print("Exception in mod %s" % mod.__name__)
|
||||
continue
|
||||
|
||||
lesson._gen_manfile()
|
||||
print("[%s] man file generated" % mod.__name__)
|
||||
|
||||
|
||||
#if __name__ == "__main__":
|
||||
# generate_manfiles()
|
|
@ -1,118 +0,0 @@
|
|||
# coding: utf-8
|
||||
"""Base classes and utils for lessons."""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import os
|
||||
import six
|
||||
import abc
|
||||
import shutil
|
||||
import warnings
|
||||
import abipy.data as abidata
|
||||
|
||||
|
||||
class BaseLesson(six.with_metaclass(abc.ABCMeta, object)):
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
mode = kwargs.get("mode")
|
||||
if mode is None: return
|
||||
|
||||
@abc.abstractproperty
|
||||
def abipy_string(self):
|
||||
"""the abipy lesson."""
|
||||
|
||||
@abc.abstractproperty
|
||||
def comline_string(self):
|
||||
"""the commandline lesson."""
|
||||
|
||||
@abc.abstractproperty
|
||||
def pyfile(self):
|
||||
"""Absolute Path of the python script."""
|
||||
|
||||
def get_local_copy(self):
|
||||
"""Copy this script to the current working dir to explore it and edit"""
|
||||
dst = os.path.basename(self.pyfile)
|
||||
if os.path.exists(dst):
|
||||
raise RuntimeError("file %s already exists. Remove it before calling get_local_copy" % dst)
|
||||
shutil.copyfile(self.pyfile, dst)
|
||||
|
||||
def __repr__(self):
|
||||
"""String representation."""
|
||||
return self.abipy_string
|
||||
|
||||
@property
|
||||
def manpath(self):
|
||||
return self.pyfile.replace(".py", ".man")
|
||||
|
||||
#def manfile(self, what=None):
|
||||
# """The path to the man file of the lesson. Use `%man %lesson.manfile` to open it in ipython"""
|
||||
# _, ext = os.path.splitext(self.pyfile)
|
||||
# man_path = self.pyfile.replace(ext, '.man')
|
||||
# try:
|
||||
# shutil.copy(os.path.join(os.path.dirname(os.path.realpath(__file__)), man_path), '.')
|
||||
# except IOError:
|
||||
# with open(man_path, "wt") as fh:
|
||||
# fh.write(self._pandoc_convert(to="man", what=what, extra_args=("-s",)))
|
||||
|
||||
def setup(self):
|
||||
lesson_name = os.path.basename(self.pyfile)[:-3]
|
||||
print("\n"
|
||||
"The lesson %s " % lesson_name + "is prepared.\n"
|
||||
"Use\n\n"
|
||||
" man ./" + lesson_name + ".man\n\n"
|
||||
"to view the text of the lesson.\n")
|
||||
|
||||
# Copy man file (except when we are running inside lessons in develop mode
|
||||
# Use. python __setup__.py to regenerate the man files.
|
||||
dst = os.path.join(os.path.abspath(os.getcwd()), os.path.basename(self.manpath))
|
||||
if not dst == self.manpath:
|
||||
shutil.copyfile(self.manpath, dst)
|
||||
self.get_local_copy()
|
||||
|
||||
def _pandoc_convert(self, to, what, extra_args=()):
|
||||
if what is None:
|
||||
what = self.abipy_string
|
||||
try:
|
||||
import pypandoc
|
||||
return pypandoc.convert(what, to, "rst", extra_args=extra_args)
|
||||
except (OSError, ImportError):
|
||||
return "pypandoc.convert failed. Please install pandoc and pypandoc"
|
||||
|
||||
def _gen_manfile(self):
|
||||
_, ext = os.path.splitext(self.pyfile)
|
||||
man_path = self.pyfile.replace(ext, '.man')
|
||||
with open(man_path, "wt") as fh:
|
||||
fh.write(self._pandoc_convert(to="man", what=self.comline_string, extra_args=("-s",)))
|
||||
|
||||
def _repr_html_(self):
|
||||
"""Support for ipython notebooks."""
|
||||
try:
|
||||
from docutils.core import publish_string
|
||||
return publish_string(self.abipy_string, writer_name="html")
|
||||
except ImportError:
|
||||
import warnings
|
||||
warnings.warn("docutils is not available. Returning raw string")
|
||||
return self.abipy_string
|
||||
|
||||
@staticmethod
|
||||
def docvar(varname):
|
||||
from abipy.abio.abivars_db import get_abinit_variables
|
||||
if varname == "inputvariable":
|
||||
return "inputvariable is a very complicated input variable. Better to ask for help immediately"
|
||||
return get_abinit_variables()[varname]
|
||||
|
||||
@property
|
||||
def abidata(self):
|
||||
"""Abipy data files."""
|
||||
return abidata
|
||||
|
||||
|
||||
def get_pseudos(structure, extension='oncvpsp'):
|
||||
"""
|
||||
returns a list of pseudos names for structure. This list should be fed to abidata.pseudos like
|
||||
abidata.pseudos(get_pseudos(structure))
|
||||
"""
|
||||
pseudos = []
|
||||
for element in structure.composition.elements:
|
||||
pseudos.append(abidata.pseudo(str(element) + '.' + extension))
|
||||
#todo test if the pseudo potential file exists
|
||||
return pseudos
|
|
@ -1,6 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""This script generate the man files of the lessons."""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
from abipy.lessons import generate_manfiles
|
||||
generate_manfiles()
|
|
@ -1,76 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
import abipy.data as abidata
|
||||
import numpy as np
|
||||
|
||||
|
||||
def gs_input(x=0.7, acell=(10, 10, 10)):
|
||||
"""H2 molecule in a big box"""
|
||||
structure = abilab.Structure.from_abivars(
|
||||
ntypat=1,
|
||||
znucl=1,
|
||||
natom=2,
|
||||
typat=(1, 1),
|
||||
xcart=[-x, 0.0, 0.0,
|
||||
+x, 0.0, 0.0],
|
||||
acell=acell,
|
||||
rprim=[1, 0, 0, 0, 1, 0, 0, 0, 1]
|
||||
)
|
||||
|
||||
inp = abilab.AbinitInput(structure=structure, pseudos=abidata.pseudos("01h.pspgth"))
|
||||
|
||||
inp.set_vars(
|
||||
ecut=10,
|
||||
nband=1,
|
||||
diemac=2.0,
|
||||
nstep=10,
|
||||
toldfe=1e-6,
|
||||
)
|
||||
|
||||
inp.set_kmesh(ngkpt=(1,1,1), shiftk=(0,0,0))
|
||||
return inp
|
||||
|
||||
|
||||
def analyze_flow(flow):
|
||||
def hh_dist(gsr):
|
||||
"""This function receives a GSR file and computes the H-H distance"""
|
||||
cart_coords = gsr.structure.cart_coords
|
||||
l = np.sqrt(np.dot(cart_coords[1] - cart_coords[0]))
|
||||
return "hh_dist", l
|
||||
|
||||
with abilab.GsrRobot.from_flow(flow) as robot:
|
||||
table = robot.get_dataframe(funcs=hh_dist)
|
||||
print(table)
|
||||
#robot.ebands_plotter().plot()
|
||||
|
||||
return table
|
||||
|
||||
|
||||
def build_flow():
|
||||
"""
|
||||
H2 molecule in a big box:
|
||||
Generate a flow to compute the total energy and forces as a function of the interatomic distance
|
||||
"""
|
||||
inputs = [gs_input(x) for x in np.linspace(0.5, 1.025, 21)]
|
||||
return flowtk.Flow.from_inputs("flow_h", inputs)
|
||||
|
||||
#table = abilab.PrettyTable(["length [Ang]", "energy [eV]"])
|
||||
#for task in flow.iflat_tasks():
|
||||
# with task.open_gsr() as gsr:
|
||||
# cart_coords = gsr.structure.cart_coords
|
||||
# l = np.sqrt(np.linalg.norm(cart_coords[1] - cart_coords[0]))
|
||||
# table.add_row([l, float(gsr.energy)])
|
||||
#print(table)
|
||||
#table.plot(title="Etotal vs interatomic distance")
|
||||
# Quadratic fit
|
||||
#fit = table.quadfit()
|
||||
#print(fit)
|
||||
#fit.plot()
|
||||
|
||||
if __name__ == "__main__":
|
||||
flow = build_flow()
|
||||
flow.make_scheduler().start()
|
||||
analyze_flow(flow)
|
|
@ -1,150 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
import abipy.data as abidata
|
||||
import numpy as np
|
||||
|
||||
|
||||
def h2_h_input(x=0.7, ecut=10, acell=(10, 10, 10)):
|
||||
"""
|
||||
This file to optimize the H2 bond length, compute the associated total
|
||||
energy, then to compute the total energy of the isolated H atom.
|
||||
"""
|
||||
h2 = abilab.Structure.from_abivars(
|
||||
natom=2,
|
||||
ntypat=1,
|
||||
typat=(1, 1),
|
||||
znucl=1,
|
||||
xcart=[-x, 0.0, 0.0,
|
||||
+x, 0.0, 0.0],
|
||||
acell=acell,
|
||||
rprim=[1, 0, 0, 0, 1, 0, 0, 0, 1],
|
||||
)
|
||||
|
||||
h = abilab.Structure.from_abivars(
|
||||
natom=1,
|
||||
ntypat=1,
|
||||
typat=1,
|
||||
znucl=1,
|
||||
xcart=[0.0, 0.0, 0.0],
|
||||
acell=acell,
|
||||
rprim=[1, 0, 0, 0, 1, 0, 0, 0, 1],
|
||||
)
|
||||
|
||||
global_vars = dict(
|
||||
ecut=ecut,
|
||||
nband=1,
|
||||
diemac=2.0,
|
||||
nstep=10,
|
||||
)
|
||||
|
||||
h2_inp = abilab.AbinitInput(structure=h2, pseudos=abidata.pseudos("01h.pspgth"))
|
||||
|
||||
h2_inp.set_vars(global_vars)
|
||||
h2_inp.set_kmesh(ngkpt=(1,1,1), shiftk=(0,0,0))
|
||||
h2_inp.set_vars(
|
||||
ionmov=3,
|
||||
ntime=10,
|
||||
tolmxf=5e-4,
|
||||
toldff=5e-5,
|
||||
)
|
||||
|
||||
h_inp = abilab.AbinitInput(structure=h, pseudos=abidata.pseudos("01h.pspgth"))
|
||||
h_inp.set_vars(global_vars)
|
||||
|
||||
h_inp.set_vars(
|
||||
nsppol=2,
|
||||
nband=(1, 1),
|
||||
occopt=2,
|
||||
occ=(1.0, 0.0),
|
||||
toldfe=1e-6,
|
||||
spinat=(0.0, 0.0, 1.0),
|
||||
)
|
||||
|
||||
return h2_inp, h_inp
|
||||
|
||||
|
||||
def ecut_convergence_study(ecuts=range(10, 40, 5)):
|
||||
"""
|
||||
H2 molecule in a big box
|
||||
Generate a flow to compute the total energy and forces as a function of the interatomic distance
|
||||
"""
|
||||
inputs = []
|
||||
for ecut in ecuts:
|
||||
inputs += h2_h_input(ecut=ecut)
|
||||
|
||||
flow = flowtk.Flow.from_inputs("flow_h2h_ecut", inputs)
|
||||
flow.make_scheduler().start()
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
with abilab.abirobot(flow, "GSR") as robot:
|
||||
frame = robot.get_dataframe()
|
||||
frame = frame[["formula", "ecut", "energy"]]
|
||||
print(frame)
|
||||
|
||||
grouped = frame.groupby("ecut")
|
||||
rows = []
|
||||
for ecut, group in grouped:
|
||||
group = group.set_index("formula")
|
||||
atomization = 2 * group["energy"]["H1"] - group["energy"]["H2"]
|
||||
atomization = abilab.Energy(atomization, "eV").to("Ha")
|
||||
rows.append(dict(ecut=ecut, atomization=atomization))
|
||||
|
||||
atomization_frame = pd.DataFrame(rows)
|
||||
print(atomization_frame)
|
||||
|
||||
atomization_frame.plot("ecut", "atomization")
|
||||
plt.show()
|
||||
|
||||
|
||||
def acell_convergence_study(acell_list=range(8, 20, 2), ecut=10):
|
||||
"""
|
||||
H2 molecule in a big box
|
||||
Generate a flow to compute the total energy and the forces as function of the interatomic distance
|
||||
"""
|
||||
inputs = []
|
||||
for acell in acell_list:
|
||||
inputs += h2_h_input(ecut=ecut, acell=3*[acell])
|
||||
flow = flowtk.Flow.from_inputs("flow_h2h_acell", inputs)
|
||||
flow.make_scheduler().start()
|
||||
|
||||
def hh_dist(gsr):
|
||||
"""This function receives a GSR file and computes the H-H distance"""
|
||||
if len(gsr.structure) == 1:
|
||||
l = None
|
||||
else:
|
||||
cart_coords = gsr.structure.cart_coords
|
||||
l = np.sqrt(np.linalg.norm(cart_coords[1] - cart_coords[0]))
|
||||
return "hh_dist", l
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
import pandas as pd
|
||||
|
||||
with abilab.abirobot(flow, "GSR") as robot:
|
||||
frame = robot.get_dataframe(funcs=hh_dist)
|
||||
frame = frame[["formula", "a", "energy", "hh_dist"]]
|
||||
print(frame)
|
||||
|
||||
grouped = frame.groupby("a")
|
||||
rows = []
|
||||
for a, group in grouped:
|
||||
group = group.set_index("formula")
|
||||
atomization = 2 * group["energy"]["H1"] - group["energy"]["H2"]
|
||||
atomization = abilab.Energy(atomization, "eV").to("Ha")
|
||||
# FIXME Values for hh_dist are wrong! why?
|
||||
rows.append(dict(a=a, atomization=atomization, hh_dist=group["hh_dist"]["H2"]))
|
||||
|
||||
atomization_frame = pd.DataFrame(rows)
|
||||
print(atomization_frame)
|
||||
|
||||
atomization_frame.plot("a", "atomization")
|
||||
plt.show()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
#ecut_convergence_study()
|
||||
acell_convergence_study()
|
|
@ -1,77 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""Optical properties with excitonic effects (Bethe-Salpeter formalism)."""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import os
|
||||
import numpy as np
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
import abipy.data as abidata
|
||||
|
||||
|
||||
def make_scf_nscf_bse_inputs(ngkpt=(6, 6, 6), ecut=6, ecuteps=3,
|
||||
mdf_epsinf=12.0, mbpt_sciss="0.8 eV"):
|
||||
"""
|
||||
Build and returns three `AbinitInput` objects to perform a
|
||||
GS-SCF + GS-NSCF + BSE calculation with the model dielectric function.
|
||||
|
||||
Args:
|
||||
ngkpt: Three integers giving the number of divisions for the k-mesh.
|
||||
ecut: Cutoff energy for the wavefunctions.
|
||||
ecuteps: Cutoff energy for the screened interation W_{GG'}.
|
||||
mdf_epsinf: Static limit of the macroscopic dielectric functions.
|
||||
Used to build the model dielectric function.
|
||||
mbpt_sciss: Scissors operator energy (used to open the initial KS gap).
|
||||
"""
|
||||
multi = abilab.MultiDataset(structure=abidata.structure_from_ucell("Si"),
|
||||
pseudos=abidata.pseudos("14si.pspnc"), ndtset=3)
|
||||
multi.set_mnemonics(True)
|
||||
|
||||
# Variables common to the three datasets.
|
||||
multi.set_vars(
|
||||
ecut=ecut,
|
||||
nband=8,
|
||||
istwfk="*1",
|
||||
diemac=12.0,
|
||||
)
|
||||
|
||||
# SCF run to get the density.
|
||||
multi[0].set_vars(tolvrs=1e-8)
|
||||
multi[0].set_kmesh(ngkpt=ngkpt, shiftk=(0, 0, 0))
|
||||
|
||||
# NSCF run on a randomly shifted k-mesh (improve the converge of optical properties)
|
||||
multi[1].set_vars(
|
||||
iscf=-2,
|
||||
nband=15,
|
||||
tolwfr=1e-8,
|
||||
chksymbreak=0, # Skip the check on the k-mesh.
|
||||
)
|
||||
|
||||
# This shift breaks the symmetry of the k-mesh.
|
||||
multi[1].set_kmesh(ngkpt=ngkpt, shiftk=(0.11, 0.21, 0.31))
|
||||
|
||||
# BSE run with Haydock iterative method (only resonant + W + v)
|
||||
multi[2].set_vars(
|
||||
optdriver=99, # BS calculation
|
||||
chksymbreak=0, # To skip the check on the k-mesh.
|
||||
bs_calctype=1, # L0 is contstructed with KS orbitals and energies.
|
||||
mbpt_sciss=mbpt_sciss, # Scissors operator used to correct the KS band structure.
|
||||
bs_exchange_term=1, # Exchange term included.
|
||||
bs_coulomb_term=21, # Coulomb term with model dielectric function.
|
||||
mdf_epsinf=mdf_epsinf, # Parameter for the model dielectric function.
|
||||
bs_coupling=0, # Tamm-Dancoff approximation.
|
||||
bs_loband=2, # Lowest band included in the calculation
|
||||
nband=6, # Highest band included in the calculation
|
||||
bs_freq_mesh="0 6 0.02 eV", # Frequency mesh for the dielectric function
|
||||
bs_algorithm=2, # Use Haydock method.
|
||||
zcut="0.15 eV", # Complex shift to avoid divergences in the continued fraction.
|
||||
ecutwfn=ecut, # Cutoff for the wavefunction.
|
||||
ecuteps=ecuteps, # Cutoff for W and /bare v.
|
||||
inclvkb=2, # The commutator for the optical limit is correctly evaluated.
|
||||
)
|
||||
|
||||
# Same shift as the one used in the previous dataset.
|
||||
multi[2].set_kmesh(ngkpt=ngkpt, shiftk=(0.11, 0.21, 0.31))
|
||||
|
||||
scf_input, nscf_input, bse_input = multi.split_datasets()
|
||||
return scf_input, nscf_input, bse_input
|
|
@ -1,42 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""DFPT lesson: phonon band structure of AlAs with Born effective charges."""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import abipy.abilab as abilab
|
||||
import abipy.data as abidata
|
||||
|
||||
|
||||
def make_scf_input(ecut=2, ngkpt=(4, 4, 4)):
|
||||
"""
|
||||
This function constructs an `AbinitInput` for performing a
|
||||
GS-SCF calculation in crystalline AlAs.
|
||||
|
||||
Args:
|
||||
ecut: cutoff energy in Ha.
|
||||
ngkpt: 3 integers specifying the k-mesh for the electrons.
|
||||
|
||||
Return:
|
||||
`AbinitInput` object
|
||||
"""
|
||||
# Initialize the AlAs structure from an internal database. Use the pseudos shipped with AbiPy.
|
||||
gs_inp = abilab.AbinitInput(structure=abidata.structure_from_ucell("AlAs"),
|
||||
pseudos=abidata.pseudos("13al.981214.fhi", "33as.pspnc"))
|
||||
|
||||
# Set the value of the Abinit variables needed for GS runs.
|
||||
gs_inp.set_vars(
|
||||
nband=4,
|
||||
ecut=ecut,
|
||||
ngkpt=ngkpt,
|
||||
nshiftk=4,
|
||||
shiftk=[0.0, 0.0, 0.5, # This gives the usual fcc Monkhorst-Pack grid
|
||||
0.0, 0.5, 0.0,
|
||||
0.5, 0.0, 0.0,
|
||||
0.5, 0.5, 0.5],
|
||||
ixc=1,
|
||||
nstep=25,
|
||||
diemac=9.0,
|
||||
tolvrs=1.0e-10,
|
||||
)
|
||||
|
||||
gs_inp.set_mnemonics(True)
|
||||
return gs_inp
|
|
@ -1,45 +0,0 @@
|
|||
.TH The "" "" "calculation of the density of states and the bandstructure"
|
||||
.SH Background
|
||||
.PP
|
||||
This lesson focuses on the calculation of density of states (DOSes) and
|
||||
of electronic band structures within the Kohn\-Sham (KS) formalism.
|
||||
.PP
|
||||
In contrast to the total energy and its derivatives, the energies of the
|
||||
KS levels have no physical meaning, except for the highest occupied
|
||||
state that actually would be the first ionization energy if the DFT XC
|
||||
functional would be exact.
|
||||
So why do we use the KS formalism to calculate electron DOSes and band
|
||||
structures?
|
||||
.PP
|
||||
As a matter of fact, the KS energy spectrum is usually in qualitative
|
||||
agreement with experiments (let\[aq]s ignore correlated systems).
|
||||
Standard KS band structures with LDA or GGA are relatively cheap and KS
|
||||
calculations allow us to make reasonable predictions and to study
|
||||
trends.
|
||||
In lesson_g0w0.py, we discuss a more accurate and expensive approach for
|
||||
the calculation of band structures and band gaps based on many\-body
|
||||
perturbation theory.
|
||||
.SH The related abinit variables
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
kptopt (negative values if band structures are wanted)
|
||||
.IP \[bu] 2
|
||||
kptbounds (the boundaries of the k\-path)
|
||||
.IP \[bu] 2
|
||||
ndivsm (number of points used to sample the smallest segment of the
|
||||
k\-path)
|
||||
.RE
|
||||
.PP
|
||||
The full description, directly from the abinit documentation, is
|
||||
available via the following function:
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abidoc.py\ man\ inputvariable
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
This will print the official abinit description of this inputvariable.
|
||||
.SH The course of this lesson
|
|
@ -1,202 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
The calculation of the density of states and the bandstructure
|
||||
==============================================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
This lesson focuses on the calculation of density of states (DOSes) and
|
||||
of electronic band structures within the Kohn-Sham (KS) formalism.
|
||||
|
||||
In contrast to the total energy and its derivatives, the energies of the KS levels have no physical meaning,
|
||||
except for the highest occupied state that actually would be the first ionization energy if the DFT XC functional would be
|
||||
exact. So why do we use the KS formalism to calculate electron DOSes and band structures?
|
||||
|
||||
As a matter of fact, the KS energy spectrum is usually in qualitative agreement with experiments (let's ignore correlated systems).
|
||||
Standard KS band structures with LDA or GGA are relatively cheap and KS calculations allow us to make
|
||||
reasonable predictions and to study trends.
|
||||
In `lesson_g0w0.py`, we discuss a more accurate and expensive approach for the calculation of band structures and band gaps
|
||||
based on many-body perturbation theory.
|
||||
|
||||
The related abinit variables
|
||||
----------------------------
|
||||
|
||||
* kptopt (negative values if band structures are wanted)
|
||||
* kptbounds (the boundaries of the k-path)
|
||||
* ndivsm (number of points used to sample the smallest segment of the k-path)
|
||||
|
||||
"""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
|
||||
_ipython_lesson_ = """
|
||||
More info on the input variables and their use can be obtained with the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(lesson.docvar("inputvariable"))
|
||||
|
||||
that prints the official description of `inputvariable`.
|
||||
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
|
||||
The flow used in this lesson contains, for the first time, dependencies.
|
||||
This means that some of the tasks in the flow can start only if its `parents` are completed.
|
||||
We will first perform a self-consistent calculation to obtain a well converged density.
|
||||
From this density we then calculate the DOS and the bandstructure in two independent tasks (non-self consistent calculations).
|
||||
Note that the DOS is computed on a regular grid of k-points because the DOS requires an integration over the first Brillouin zone.
|
||||
For the band structure, we use a high symmetry path inside the BZ.
|
||||
|
||||
Start this lesson by importing it in a new namespace:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from abipy.lessons.lesson_dos_bands import Lesson
|
||||
lesson = Lesson()
|
||||
|
||||
As usual, you can reread this text using the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson
|
||||
|
||||
To build the flow:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow = lesson.make_flow()
|
||||
|
||||
To print the input files:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_inputs()
|
||||
|
||||
To visualize the dependencies in the flow:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_dependencies()
|
||||
|
||||
Start the flow with the scheduler and wait for completion.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
To analyze the results.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.analyze(flow)
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
At this point, you may want to interact more with the underlying python objects
|
||||
so that you can start to develop your script or your post-processing tools.
|
||||
|
||||
Our flow consists of a `BandStructureWork` object that provides many tools for the post-processing.
|
||||
Use
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
work = flow[0]
|
||||
|
||||
to access the band structure work and look at the `plot` methods that
|
||||
are available (hint: type work.plot in ipython and press TAB to get a list of methods)
|
||||
|
||||
1) Use the `plot_` methods to visualize the convergence of the DOS wrt to the number of k-points.
|
||||
Then change the value of the gaussian broadening (`width` parameter).
|
||||
|
||||
2) Plot bands and DOS on the same figure.
|
||||
|
||||
Remember that, in ipython, one can access the documentation with `work.plot_edoses?`
|
||||
|
||||
Next
|
||||
----
|
||||
|
||||
A logical next lesson would be lesson_g0w0
|
||||
"""
|
||||
|
||||
_commandline_lesson_ = """
|
||||
The full description, directly from the abinit documentation, is available via the following function:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abidoc.py man inputvariable
|
||||
|
||||
This will print the official abinit description of this inputvariable.
|
||||
|
||||
|
||||
The course of this lesson
|
||||
-------------------------
|
||||
"""
|
||||
|
||||
import os
|
||||
import abipy.abilab as abilab
|
||||
import abipy.data as abidata
|
||||
import abipy.flowtk as flowtk
|
||||
from abipy.lessons.core import BaseLesson, get_pseudos
|
||||
|
||||
|
||||
def make_electronic_structure_flow(ngkpts_for_dos=((2, 2, 2), (4, 4, 4), (6, 6, 6), (8, 8, 8))):
|
||||
"""Band structure calculation."""
|
||||
multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"),
|
||||
pseudos=abidata.pseudos("14si.pspnc"), ndtset=2 + len(ngkpts_for_dos))
|
||||
# Global variables
|
||||
multi.set_vars(ecut=10)
|
||||
|
||||
# Dataset 1
|
||||
multi[0].set_vars(tolvrs=1e-9)
|
||||
multi[0].set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0])
|
||||
|
||||
# Dataset 2
|
||||
multi[1].set_vars(tolwfr=1e-15)
|
||||
multi[1].set_kpath(ndivsm=5)
|
||||
|
||||
# Dataset 3
|
||||
for i, ngkpt in enumerate(ngkpts_for_dos):
|
||||
multi[2+i].set_vars(tolwfr=1e-15)
|
||||
multi[2+i].set_kmesh(ngkpt=ngkpt, shiftk=[0,0,0])
|
||||
|
||||
inputs = multi.split_datasets()
|
||||
scf_input, nscf_input, dos_input = inputs[0], inputs[1], inputs[2:]
|
||||
|
||||
return flowtk.bandstructure_flow(workdir="flow_dos_bands", scf_input=scf_input, nscf_input=nscf_input,
|
||||
dos_inputs=dos_input)
|
||||
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return __doc__ + _ipython_lesson_
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return __doc__ + _commandline_lesson_
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return os.path.abspath(__file__).replace(".pyc", ".py")
|
||||
|
||||
@staticmethod
|
||||
def make_flow(**kwargs):
|
||||
return make_electronic_structure_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze(flow):
|
||||
nscf_task = flow[0][1]
|
||||
with nscf_task.open_gsr() as gsr:
|
||||
return gsr.ebands.plot()
|
||||
|
||||
if __name__ == "__main__":
|
||||
lesson = Lesson()
|
||||
flow = lesson.make_flow()
|
||||
flow.make_scheduler().start()
|
||||
#flow.build_and_pickle_dump()
|
||||
#lesson.setup()
|
|
@ -1,68 +0,0 @@
|
|||
.TH Basis "" "" "set convergence study and more info on flows, works, and tasks"
|
||||
.SH Background
|
||||
.PP
|
||||
This lesson focuses on the convergence study on the completeness of the
|
||||
plane wave (PW) basis set.
|
||||
Plane waves are inherently well suited to capture the periodic nature of
|
||||
crystalline solids.
|
||||
In addition, a PW basis set has the advantage that it introduces only
|
||||
one convergence parameter, the kinetic energy cutoff (ecut).
|
||||
.PP
|
||||
The sharp features of the wavefunctions near the nucleus are however
|
||||
problematic for PWs.
|
||||
Describing these features would require very high energy cutoff
|
||||
energies.
|
||||
For this reason PW codes use pseudo\-potentials in order to facilitate
|
||||
the convergence of the results.
|
||||
A pseudopotential replaces the singular coulomb potential of the nucleus
|
||||
and the core electrons by something smoother inside the so\-called
|
||||
pseudization region.
|
||||
The pseudopotential connects smoothly to the real all\-electron
|
||||
potential outside the pseudization region.
|
||||
.PP
|
||||
Note that different pseudo potentials usually require a different cutoff
|
||||
energy to be converged.
|
||||
In general norm\-conserving pseudos require a larger cut\-off than
|
||||
ultra\-soft pseudos or Projector Augmented Wave \[aq]pseudos\[aq].
|
||||
Moreover two pseudos of the same type for the same element may require
|
||||
different cutoff energies as well.
|
||||
Pseudos with small pseudization radius usually require larger cutoffs
|
||||
than pseudos with large pseudization radius.
|
||||
.SH The related abinit variables
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
ecut (cutoff energy)
|
||||
.IP \[bu] 2
|
||||
pawecutdg (additional variable for the double\-grid used in PAW)
|
||||
.IP \[bu] 2
|
||||
ecutsm (smoothing of the kinetic energy)
|
||||
.RE
|
||||
.PP
|
||||
The full description, directly from the abinit documentation, is
|
||||
available via the shell command:
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abidoc.py\ man\ inputvariable
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
that prints the official description of inputvariable.
|
||||
.SH The course of this lesson
|
||||
.PP
|
||||
As in the previous lesson, executing the python script creates the
|
||||
folder structure with the required input files.
|
||||
.PP
|
||||
One of the standard thing to look for to be converged in the total
|
||||
energy.
|
||||
We did that already in the previous lesson.
|
||||
This time have a look at some of the other important properties.
|
||||
Look for instance at the convergence rate of the forces, stress\-tensor
|
||||
or the energies of the KS\-orbitals.
|
||||
.SH Exercises
|
||||
.PP
|
||||
Edit the input files to run the same convergence study for a different
|
||||
k\-point mesh.
|
||||
Best to start small.
|
|
@ -1,219 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
Basis set convergence study and more info on flows, works, and tasks
|
||||
====================================================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
This lesson focuses on the convergence study on the completeness of the plane wave (PW) basis set.
|
||||
Plane waves are inherently well suited to capture the periodic nature of crystalline solids.
|
||||
In addition, a PW basis set has the advantage that it introduces only one convergence parameter,
|
||||
the kinetic energy cutoff (ecut).
|
||||
|
||||
The sharp features of the wavefunctions near the nucleus are however problematic for PWs.
|
||||
Describing these features would require very high energy cutoff energies.
|
||||
For this reason PW codes use pseudo-potentials in order to facilitate the convergence of the results.
|
||||
A pseudopotential replaces the singular coulomb potential of the nucleus and the
|
||||
core electrons by something smoother inside the so-called pseudization region.
|
||||
The pseudopotential connects smoothly to the real all-electron potential outside the pseudization region.
|
||||
|
||||
Note that different pseudo potentials usually require a different cutoff energy to be converged.
|
||||
In general norm-conserving pseudos require a larger cut-off than ultra-soft pseudos
|
||||
or Projector Augmented Wave 'pseudos'.
|
||||
Moreover two pseudos of the same type for the same element may require different cutoff energies as well.
|
||||
Pseudos with small pseudization radius usually require larger cutoffs than pseudos
|
||||
with large pseudization radius.
|
||||
|
||||
The related abinit variables
|
||||
----------------------------
|
||||
|
||||
* ecut (cutoff energy)
|
||||
* pawecutdg (additional variable for the double-grid used in PAW)
|
||||
* ecutsm (smoothing of the kinetic energy)
|
||||
|
||||
"""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
_ipython_lesson_ = """
|
||||
More info on the input variables and their use can be obtained using:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(lesson.docvar("inputvariable"))
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
This lesson contains a factory function for a convergence study with respect to ecut.
|
||||
|
||||
Executing the lesson
|
||||
--------------------
|
||||
|
||||
Start this lesson by importing it:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from abipy.lessons.lesson_ecut_convergence import Lesson
|
||||
lesson = Lesson()
|
||||
|
||||
As usual, you can reread this text using the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson
|
||||
|
||||
To build the flow:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow = lesson.make_ecut_flow()
|
||||
|
||||
To print the input files
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_inputs()
|
||||
|
||||
to show the status of a flow:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_status()
|
||||
|
||||
There are many more properties and methods of the flow than may also come in handy.
|
||||
By typing [tab] in ipython after the period, you will be presented
|
||||
with all the options. Feel free to experiment a bit at this point.
|
||||
In the ipython shell, one can get the description of the object by
|
||||
adding a question mark at the end of the statement:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_status?
|
||||
|
||||
Start the flow with the scheduler and wait for completion.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
To analyze the results.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.analyze(flow)
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
Try to run the convergence study for Al.
|
||||
|
||||
Get a copy of the python script used in this lesson like before and look at the `analyze` method.
|
||||
Use the code in `analyze` to build your Pandas dataframe and use its method to produce convergence plots:
|
||||
|
||||
Next
|
||||
----
|
||||
|
||||
A logical next lesson would be lesson_relaxation
|
||||
|
||||
"""
|
||||
|
||||
_commandline_lesson_ = """
|
||||
The full description, directly from the abinit documentation, is available via the shell command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abidoc.py man inputvariable
|
||||
|
||||
that prints the official description of inputvariable.
|
||||
|
||||
The course of this lesson
|
||||
-------------------------
|
||||
|
||||
As in the previous lesson, executing the python script creates the folder structure with the required input files.
|
||||
|
||||
One of the standard thing to look for to be converged in the total energy. We did that already in the previous lesson.
|
||||
This time have a look at some of the other important properties. Look for instance at the convergence rate of the
|
||||
forces, stress-tensor or the energies of the KS-orbitals.
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
Edit the input files to run the same convergence study for a different k-point mesh. Best to start small.
|
||||
"""
|
||||
|
||||
import os
|
||||
import abipy.abilab as abilab
|
||||
import abipy.data as abidata
|
||||
import abipy.flowtk as flowtk
|
||||
from abipy.lessons.core import BaseLesson
|
||||
|
||||
|
||||
def make_ecut_flow(structure_file=None, ecut_list = (10, 12, 14, 16, 18)):
|
||||
"""
|
||||
Build and return a `Flow` to perform a convergence study wrt to ecut.
|
||||
|
||||
Args:
|
||||
structure_file: (optional) file containing the crystalline structure.
|
||||
If None, crystalline silicon structure.
|
||||
ecut_list: List of cutoff energies to be investigated.
|
||||
"""
|
||||
# Define the structure and add the necessary pseudos:
|
||||
if structure_file is None:
|
||||
multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"),
|
||||
pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ecut_list))
|
||||
workdir = "flow_Si_ecut_convergence"
|
||||
else:
|
||||
structure = abilab.Structure.from_file(structure_file)
|
||||
pseudos = abilab.PseudoTable() ## todo fix this
|
||||
multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=len(ecut_list))
|
||||
workdir = "flow_" + structure.composition.reduced_formula + "_ecut_convergence"
|
||||
|
||||
# Add mnemonics to the input files.
|
||||
multi.set_mnemonics(True)
|
||||
|
||||
# Global variables
|
||||
multi.set_vars(tolvrs=1e-9)
|
||||
multi.set_kmesh(ngkpt=[4, 4, 4], shiftk=[0, 0, 0])
|
||||
|
||||
# Here we set the value of ecut used by the i-th task.
|
||||
for i, ecut in enumerate(ecut_list):
|
||||
multi[i].set_vars(ecut=ecut)
|
||||
|
||||
return flowtk.Flow.from_inputs(workdir=workdir, inputs=multi.split_datasets())
|
||||
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return __doc__ + _ipython_lesson_
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return __doc__ + _commandline_lesson_
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return os.path.abspath(__file__).replace(".pyc", ".py")
|
||||
|
||||
@staticmethod
|
||||
def make_ecut_flow(**kwargs):
|
||||
return make_ecut_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze(flow, **kwargs):
|
||||
with abilab.abirobot(flow, "GSR") as robot:
|
||||
data = robot.get_dataframe()
|
||||
|
||||
import matplotlib.pyplot as plt
|
||||
ax = data.plot(x="ecut", y="energy", title="Total energy vs ecut", legend=False, style="b-o")
|
||||
ax.set_xlabel('Ecut [Ha]')
|
||||
ax.set_ylabel('Total Energy [eV]')
|
||||
return plt.show(**kwargs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
lesson = Lesson()
|
||||
flow = lesson.make_ecut_flow()
|
||||
flow.build_and_pickle_dump()
|
||||
lesson.setup()
|
|
@ -1,57 +0,0 @@
|
|||
.TH $G_0W_0$ "" "" "band structure with an energy\-dependent scissors operator"
|
||||
.SH Background
|
||||
.PP
|
||||
Standard functionals (LDA and GGA), systematically underestimate band
|
||||
gaps, giving values that are about 30\-40% smaller than experimental
|
||||
data.
|
||||
The inability of standard Kohn\-Sham (KS) theory to give band gaps close
|
||||
to experiment is often referred to as the \f[B]band\-gap problem\f[].
|
||||
From a theoretical point of view this is not surprising since KS
|
||||
eigenvalues are not supposed to give the correct band energies.
|
||||
The band structure of a crystal is rigorously defined as the energies
|
||||
needed to add or subtract electrons from the many\-body system which, in
|
||||
turn, are related to the difference between total energies of many\-body
|
||||
states differing by one electron.
|
||||
.PP
|
||||
An alternative, more traditional, approach to the study of
|
||||
exchange\-correlation effects in many\-body systems is provided by
|
||||
Many\-Body Perturbation Theory (MBPT) which defines a rigorous approach
|
||||
to the description of excited\-state properties, based on the
|
||||
Green\[aq]s function formalism.
|
||||
In this lesson, we discuss how to use the MBPT part of ABINIT to compute
|
||||
the band\-structure of silicon within the so\-called $G_0W_0$
|
||||
approximation.
|
||||
.PP
|
||||
For a very brief introduction to the many\-body formalism, see
|
||||
MBPTNNOTES (http://www.abinit.org/documentation/helpfiles/for-v7.10/tutorial/theory_mbt.html).
|
||||
.SH Related ABINIT variables
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
optdriver
|
||||
.IP \[bu] 2
|
||||
ecuteps
|
||||
.IP \[bu] 2
|
||||
ecutsigx
|
||||
.IP \[bu] 2
|
||||
nband
|
||||
.IP \[bu] 2
|
||||
gwcalctyp
|
||||
.IP \[bu] 2
|
||||
gw_qprange
|
||||
.IP \[bu] 2
|
||||
all gw** variables
|
||||
.RE
|
||||
.PP
|
||||
The full description, directly from the abinit documentation, is
|
||||
available via the following shell command:
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abidoc.py\ man\ inputvariable
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
This command will print the official description of inputvariable.
|
||||
.SH The course of this lesson
|
|
@ -1,343 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
$G_0W_0$ band structure with an energy-dependent scissors operator
|
||||
==================================================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
Standard functionals (LDA and GGA), systematically underestimate band gaps, giving values
|
||||
that are about 30-40% smaller than experimental data.
|
||||
The inability of standard Kohn-Sham (KS) theory to give band gaps close to experiment is often referred to as the **band-gap problem**.
|
||||
From a theoretical point of view this is not surprising since KS eigenvalues are not supposed to give the correct band energies.
|
||||
The band structure of a crystal is rigorously defined as the energies needed to add or subtract electrons from the many-body system
|
||||
which, in turn, are related to the difference between total energies of many-body states differing by one electron.
|
||||
|
||||
An alternative, more traditional, approach to the study of exchange-correlation effects in
|
||||
many-body systems is provided by Many-Body Perturbation Theory (MBPT) which defines a rigorous approach to the description
|
||||
of excited-state properties, based on the Green's function formalism.
|
||||
In this lesson, we discuss how to use the MBPT part of ABINIT to compute the band-structure of silicon
|
||||
within the so-called $G_0W_0$ approximation.
|
||||
|
||||
For a very brief introduction to the many-body formalism, see MBPT_NOTES_.
|
||||
|
||||
.. _MBPT_NOTES: http://www.abinit.org/documentation/helpfiles/for-v7.10/tutorial/theory_mbt.html
|
||||
|
||||
Related ABINIT variables
|
||||
------------------------
|
||||
|
||||
* optdriver
|
||||
* ecuteps
|
||||
* ecutsigx
|
||||
* nband
|
||||
* gwcalctyp
|
||||
* gw_qprange
|
||||
* all gw** variables
|
||||
|
||||
"""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
_ipython_lesson_ = """
|
||||
More info on the input variables and it's usage can be obtained using the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.abinit_help(inputvariable)
|
||||
|
||||
that prints the official description of the variables.
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
|
||||
In this lesson, we will construct an `abipy` flow made of two works.
|
||||
The first work is a standard KS band-structure calculation that consists of
|
||||
an initial GS calculation to get the density followed by two NSCF calculations.
|
||||
The first NSCF task computes the KS eigenvalues on a high-symmetry path in the BZ,
|
||||
whereas the second NSCF task employs a homogeneous k-mesh so that one can compute
|
||||
the DOS from the KS eigenvalues.
|
||||
This work is similar to the one we have already encountered in lesson_dos_bands.
|
||||
|
||||
The second work represents the real GW workflow that uses the density computed in the first task of
|
||||
the previous work to compute the KS bands for many empty states.
|
||||
The WFK file produced in this step is then used to compute the screened interaction $W$.
|
||||
Finally, we perform a self-energy calculation that uses the $W$ produced
|
||||
in the previous step and the WFK file to compute the matrix elements of the self-energy and
|
||||
the $G_0W_0$ corrections for all the k-points in the IBZ and 8 bands (4 occupied + 4 empty)
|
||||
|
||||
Once the flow is completed, we can interpolate the $G_0W_0$ corrections as function of the initial KS energy
|
||||
to obtain an energy-dependent scissors operator.
|
||||
At this point, we can apply the scissors operator onto the KS band structure to obtain
|
||||
an approximated $G_0W_0$ band dispersion.
|
||||
|
||||
Don't worry if there are steps of the entire procedure that are not clear to you.
|
||||
GW calculations are much more complicated than standard KS band structures and
|
||||
the main goal of this lesson is to give you an overview of the Abipy capabilities.
|
||||
|
||||
Executing the lesson
|
||||
--------------------
|
||||
|
||||
This lesson can be started in ipython by importing it with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from abipy.lessons.lesson_g0w0 import Lesson
|
||||
lesson = Lesson()
|
||||
|
||||
The `lesson` object gives us all the tools needed to execute this tutorial. As usual:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson
|
||||
|
||||
displays this text.
|
||||
|
||||
The lesson module provides a factory function that returns a flow designed to perform standard G0W0 calculations.
|
||||
To build the flow, use
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow = lesson.make_flow()
|
||||
|
||||
`flow` is the object containing al the information needed to generate abinit inputs.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_inputs()
|
||||
|
||||
displays all the inputs that will be 'passed' to abinit.
|
||||
|
||||
To start the execution of calculations packed in this flow we use the following command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
This starts the actual execution via a scheduler.
|
||||
|
||||
The last step of analyzing the results can be done again in with a single command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.analyze(flow)
|
||||
|
||||
This method of flow will open the necessary output files, retrieve the data, and produce a plot.
|
||||
|
||||
Finally, once you have completed this lesson you can exit ipython with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
exit
|
||||
|
||||
You can see that in the working directory, here is
|
||||
now a subdir were the calculation have been performed.
|
||||
Have a look at these folders and the files that are in them.
|
||||
|
||||
Next
|
||||
----
|
||||
|
||||
A logical next lesson would be lesson_bse.
|
||||
Please consult the ipython notebook available on the abipy website
|
||||
"""
|
||||
|
||||
_commandline_lesson_ = """
|
||||
The full description, directly from the abinit documentation, is available via the following shell command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abidoc.py man inputvariable
|
||||
|
||||
This command will print the official description of inputvariable.
|
||||
|
||||
The course of this lesson
|
||||
-------------------------
|
||||
|
||||
"""
|
||||
import os
|
||||
import abipy.data as abidata
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
|
||||
from abipy.lessons.core import BaseLesson
|
||||
|
||||
|
||||
def make_inputs(ngkpt, paral_kgb=0):
|
||||
"""
|
||||
Crystalline silicon: calculation of the G0W0 band structure with the scissors operator.
|
||||
|
||||
Args:
|
||||
ngkpt: list of 3 integers. Abinit variable defining the k-point sampling.
|
||||
paral_kgb: Option used to select the eigensolver in the GS part.
|
||||
|
||||
Return:
|
||||
Six AbinitInput objects:
|
||||
|
||||
0: ground state run to get the density.
|
||||
1: NSCF run to get the KS band structure on a high-symmetry k-path.
|
||||
2: NSCF run with a homogeneous sampling of the BZ to compute the KS DOS.
|
||||
3: NSCF run with empty states to prepare the GW steps.
|
||||
4: calculation of the screening from the WFK file computed in dataset 4.
|
||||
5: Use the SCR file computed at step 5 and the WFK file computed in dataset 4 to get the GW corrections.
|
||||
"""
|
||||
|
||||
multi = abilab.MultiDataset(abidata.cif_file("si.cif"),
|
||||
pseudos=abidata.pseudos("14si.pspnc"), ndtset=6)
|
||||
# Add mnemonics to input file.
|
||||
multi.set_mnemonics(True)
|
||||
|
||||
# This grid is the most economical, but does not contain the Gamma point.
|
||||
scf_kmesh = dict(
|
||||
ngkpt=ngkpt,
|
||||
shiftk=[0.5, 0.5, 0.5,
|
||||
0.5, 0.0, 0.0,
|
||||
0.0, 0.5, 0.0,
|
||||
0.0, 0.0, 0.5]
|
||||
)
|
||||
|
||||
dos_kmesh = dict(
|
||||
ngkpt=(6, 6, 6),
|
||||
shiftk=[0.0, 0.0, 0.0])
|
||||
|
||||
# This grid contains the Gamma point, which is the point at which
|
||||
# we will compute the (direct) band gap.
|
||||
gw_kmesh = dict(
|
||||
ngkpt=ngkpt,
|
||||
shiftk=[0.0, 0.0, 0.0,
|
||||
0.0, 0.5, 0.5,
|
||||
0.5, 0.0, 0.5,
|
||||
0.5, 0.5, 0.0]
|
||||
)
|
||||
|
||||
# Global variables
|
||||
ecut = 6
|
||||
multi.set_vars(
|
||||
ecut=ecut,
|
||||
istwfk="*1",
|
||||
paral_kgb=paral_kgb,
|
||||
gwpara=2,
|
||||
)
|
||||
|
||||
# Dataset 1 (GS run to get the density)
|
||||
multi[0].set_kmesh(**scf_kmesh)
|
||||
multi[0].set_vars(
|
||||
tolvrs=1e-6,
|
||||
nband=4,
|
||||
)
|
||||
multi[0].set_kmesh(**scf_kmesh)
|
||||
|
||||
# Dataset 2 (NSCF run)
|
||||
multi[1].set_vars(iscf=-2,
|
||||
tolwfr=1e-12,
|
||||
nband=8,
|
||||
)
|
||||
multi[1].set_kpath(ndivsm=8)
|
||||
|
||||
# Dataset 3 (DOS NSCF)
|
||||
multi[2].set_vars(iscf=-2,
|
||||
tolwfr=1e-12,
|
||||
nband=35,
|
||||
#nband=10,
|
||||
)
|
||||
multi[2].set_kmesh(**dos_kmesh)
|
||||
|
||||
# Dataset 4 (NSCF run for GW)
|
||||
multi[3].set_vars(iscf=-2,
|
||||
tolwfr=1e-12,
|
||||
nband=35,
|
||||
)
|
||||
multi[3].set_kmesh(**gw_kmesh)
|
||||
|
||||
# Dataset3: Calculation of the screening.
|
||||
multi[4].set_vars(
|
||||
optdriver=3,
|
||||
nband=25,
|
||||
ecutwfn=ecut,
|
||||
symchi=1,
|
||||
inclvkb=0,
|
||||
ecuteps=4.0,
|
||||
)
|
||||
multi[4].set_kmesh(**gw_kmesh)
|
||||
|
||||
multi[5].set_vars(
|
||||
optdriver=4,
|
||||
nband=10,
|
||||
ecutwfn=ecut,
|
||||
ecuteps=4.0,
|
||||
ecutsigx=6.0,
|
||||
symsigma=1,
|
||||
gw_qprange=-4, # Compute GW corrections for all kpts in IBZ,
|
||||
# all occupied states and 4 empty states,
|
||||
)
|
||||
multi[5].set_kmesh(**gw_kmesh)
|
||||
|
||||
return multi.split_datasets()
|
||||
|
||||
|
||||
def make_g0w0_scissors_flow(workdir="flow_lesson_g0w0", ngkpt=(2,2,2)):
|
||||
# Change the value of ngkpt below to perform a GW calculation with a different k-mesh.
|
||||
scf, bands_nscf, dos_nscf, gw_nscf, scr, sig = make_inputs(ngkpt=ngkpt)
|
||||
|
||||
flow = flowtk.Flow(workdir=workdir)
|
||||
work0 = flowtk.BandStructureWork(scf, bands_nscf, dos_inputs=dos_nscf)
|
||||
flow.register_work(work0)
|
||||
|
||||
work1 = flowtk.Work()
|
||||
gw_nscf_task = work1.register_nscf_task(gw_nscf, deps={work0[0]: "DEN"})
|
||||
scr_task = work1.register_scr_task(scr, deps={gw_nscf_task: "WFK"})
|
||||
sigma_task = work1.register_sigma_task(sig, deps={gw_nscf_task: "WFK", scr_task: "SCR"})
|
||||
flow.register_work(work1)
|
||||
|
||||
return flow.allocate()
|
||||
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return __doc__ + _ipython_lesson_
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return __doc__ + _commandline_lesson_
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return os.path.abspath(__file__).replace(".pyc", ".py")
|
||||
|
||||
@staticmethod
|
||||
def make_flow(**kwargs):
|
||||
return make_g0w0_scissors_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze(flow, domains_spin=((-10, 6.02), (6.1, 20))):
|
||||
# Read the G0W0 correction form the output file of the sigma_task
|
||||
# and construct the scissors_builder object.
|
||||
sigma_task = flow[1][2]
|
||||
builder = sigma_task.get_scissors_builder()
|
||||
|
||||
# Plot G0W0 results as function of the initial KS energy.
|
||||
builder.plot_qpe_vs_e0()
|
||||
|
||||
# Build the scissors operator with a polyfit in the regions specified by domains_spin
|
||||
builder.build(domains_spin=domains_spin)
|
||||
|
||||
# Plot the fit.
|
||||
builder.plot_fit()
|
||||
|
||||
# Here we pass the KS bands to the scissors-builder.
|
||||
# plot_qpbands with apply the scissors onto the input band structure and plot the final results.
|
||||
bands_task = flow[0][1]
|
||||
bands_filepath = bands_task.gsr_path
|
||||
builder.plot_qpbands(bands_filepath, bands_label="KS Bands", title="Silicon Bands (KS and KS+scissors)")
|
||||
|
||||
# TODO: Fix problems with boundaries!
|
||||
#dos_task = flow[0][2]
|
||||
#dos_filepath = dos_task.outdir.has_abiext("GSR")
|
||||
#builder.plot_qpbands(bands_filepath, dos_filepath=dos_filepath,
|
||||
# title="Silicon Bands and DOS (KS and KS+scissors)")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
lesson = Lesson()
|
||||
flow = lesson.make_flow()
|
||||
flow.build_and_pickle_dump()
|
||||
lesson.setup()
|
|
@ -1,139 +0,0 @@
|
|||
.TH K\-point "" "" "convergence study for a semi\-conductor"
|
||||
.SH Background
|
||||
.PP
|
||||
This lesson deals with the basic k\-point convergence study that is
|
||||
needed in any DFT calculation in periodic systems.
|
||||
In such systems, indeed, the first Brillouin zone (BZ) needs to be
|
||||
discretized when performing the integration of several important
|
||||
quantities e.g.
|
||||
the electronic density or the electronic energy.
|
||||
Integrals over the BZ are therefore turned into sums over discrete
|
||||
k\-points and the k\-mesh should be dense enough, but at the same time
|
||||
as coarse as possible to make for an efficient calculation.
|
||||
Your first investigation into a new compound will often be a k\-point
|
||||
convergence study.
|
||||
.PP
|
||||
It is worth stressing that the density of the k\-mesh needed to reach
|
||||
converged results is system\-dependent.
|
||||
Note that metals need much denser k\-meshes than semiconductors.
|
||||
The presence of the Fermi surface, indeed, introduces discontinuities in
|
||||
the integrand functions and a fictitious broadening of the occupation
|
||||
factors (tsmear) should be introduced in order to accelerate the
|
||||
convergence of the integrals.
|
||||
.SH The related Abinit variables
|
||||
.PP
|
||||
The variables used to specify the k\-point sampling are:
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
ngkpt
|
||||
.IP \[bu] 2
|
||||
shiftk
|
||||
.IP \[bu] 2
|
||||
kptopt (see exercises)
|
||||
.RE
|
||||
.PP
|
||||
The variables used to specify the occupation scheme in metals are:
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
occopt (see exercises)
|
||||
.IP \[bu] 2
|
||||
tsmear (see exercises)
|
||||
.RE
|
||||
.PP
|
||||
For a more detailed description of the variables, you are invited to
|
||||
consult the abinit documentation.
|
||||
The full description, directly from the official abinit docs, is
|
||||
available via the shell command:
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abidoc.py\ man\ inputvariable
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
that prints the official description of inputvariable.
|
||||
.SH Description of the lesson
|
||||
.PP
|
||||
In the generation of this lesson by the python script all the input
|
||||
files have been generated automatically.
|
||||
The input files have been organized in a workdir
|
||||
"flow_lesson_Si_kpoint_convergence".
|
||||
Inside this directory, you\[aq]ll find a single work, w0, with four
|
||||
tasks, t0\-t1\-t2\-t3.
|
||||
Have a look at the input files, run.abi, of the four tasks to see what
|
||||
is different.
|
||||
.PP
|
||||
You\[aq]ll see that also the files file and the jobs submission script
|
||||
have been generated.
|
||||
In the job scripts you\[aq]ll see that the jobs are prepared to run just
|
||||
on the front end.
|
||||
.PP
|
||||
You\[aq]ll also see that the files file has been created as well.
|
||||
.PP
|
||||
To perform the k\-point convergence study execute, abinit with the four
|
||||
input sets.
|
||||
.PP
|
||||
Once the calculations are ready, you\[aq]ll see three important output
|
||||
files.
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
run.out
|
||||
.IP \[bu] 2
|
||||
run.log
|
||||
.IP \[bu] 2
|
||||
run.err
|
||||
.RE
|
||||
.PP
|
||||
The main summary of the calculation can be found in the .out file,
|
||||
we\[aq]ll go there soon :\-).
|
||||
The .err file should be empty.
|
||||
If it\[aq]s not something went wrong.
|
||||
If something went wrong read the .err.
|
||||
file.
|
||||
The .log file contains extensive information on you calculation that
|
||||
could help to find out what went wrong in the case of errors.
|
||||
Especially there are three types of messages that could help
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
COMMENT
|
||||
.IP \[bu] 2
|
||||
WARNING
|
||||
.IP \[bu] 2
|
||||
ERROR
|
||||
.RE
|
||||
.PP
|
||||
In case of an error message abinit stopped the execution by itself,
|
||||
because of that error.
|
||||
.PP
|
||||
Now the .out file.
|
||||
Some interesting keywords to look for:
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
Symmetries
|
||||
.IP \[bu] 2
|
||||
Citation for XC functional:
|
||||
.IP \[bu] 2
|
||||
ETOT (the total energies during the electronic structure convergence)
|
||||
.IP \[bu] 2
|
||||
Eigenvalues
|
||||
.IP \[bu] 2
|
||||
Etotal (the total energy of an ionic step)
|
||||
.RE
|
||||
.PP
|
||||
Obviously there is much more.
|
||||
.PP
|
||||
Collect the total energies of the four calculations and plot them as a
|
||||
function of the number of k\-points in the calculation.
|
||||
.PP
|
||||
Alternative to execution of the manual execution the calculations can
|
||||
also be executed using the abipy scheduler.
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abirun.py\ flow_lesson_Si_kpoint_convergence\ scheduler
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
|
@ -1,306 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
K-point convergence study for a semi-conductor
|
||||
===============================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
This lesson deals with the basic k-point convergence study that is needed in any DFT calculation in periodic systems.
|
||||
In such systems, indeed, the first Brillouin zone (BZ) needs to be discretized when performing the
|
||||
integration of several important quantities e.g. the electronic density or the electronic energy.
|
||||
Integrals over the BZ are therefore turned into sums over discrete k-points and the k-mesh should
|
||||
be dense enough, but at the same time as coarse as possible to make for an efficient calculation.
|
||||
Your first investigation into a new compound will often be a k-point convergence study.
|
||||
|
||||
It is worth stressing that the density of the k-mesh needed to reach converged results is system-dependent.
|
||||
Note that metals need much denser k-meshes than semiconductors.
|
||||
The presence of the Fermi surface, indeed, introduces discontinuities in the integrand functions and a
|
||||
fictitious broadening of the occupation factors (tsmear) should be introduced in order to accelerate
|
||||
the convergence of the integrals.
|
||||
|
||||
The related Abinit variables
|
||||
----------------------------
|
||||
|
||||
The variables used to specify the k-point sampling are:
|
||||
|
||||
* ngkpt
|
||||
* shiftk
|
||||
* kptopt (see exercises)
|
||||
|
||||
The variables used to specify the occupation scheme in metals are:
|
||||
|
||||
* occopt (see exercises)
|
||||
* tsmear (see exercises)
|
||||
|
||||
|
||||
"""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
_ipython_lesson_ = """
|
||||
For a more detailed description of the variables, you are invited to consult the abinit documentation.
|
||||
The full description, directly from the official abinit docs, is available in ipython with the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(lesson.docvar("inputvariable"))
|
||||
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
|
||||
When performed manually, a k-point convergence study would require
|
||||
the preparation of several input files, running abinit for all
|
||||
the inputs and then extracting and studying the quantity under investigation.
|
||||
This lesson shows how this process can be facilitated thanks to abipy.
|
||||
|
||||
We will construct a single python object, an abipy flow, that contains all
|
||||
the information needed for the calculations.
|
||||
The flow also provides methods for running abinit, inspecting the input and the output
|
||||
as well tools for analyzing the final results.
|
||||
|
||||
Executing the lesson
|
||||
--------------------
|
||||
|
||||
This lesson can be started in ipython by importing it with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from abipy.lessons.lesson_kpoint_convergence import Lesson
|
||||
lesson = Lesson()
|
||||
|
||||
This `lesson` module gives us all the tools needed for the exercises.
|
||||
For instance the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson
|
||||
|
||||
displays this text and can be recalled at any moment.
|
||||
|
||||
The main object we use to connect different calculations is the AbiPy flow.
|
||||
The lesson module provides a method that builds and returns a flow to perform k-point convergence studies.
|
||||
The flow is constructed with the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow = lesson.make_ngkpt_flow()
|
||||
|
||||
In this case make_ngkpt_flow builds a flow for silicon since no argument is passed to the function.
|
||||
|
||||
Our flow has several useful methods. For instance:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.show_inputs()
|
||||
|
||||
displays all the inputs that will be 'passed' to abinit.
|
||||
|
||||
To start the calculation inside the python shell, use the following command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
The scheduler is a sort of daemon that submits all the tasks that are ready to run.
|
||||
In our case all the tasks in the flow are independent so the first
|
||||
cycle of the scheduler will submit all the tasks in the flow.
|
||||
More complicated flows may have tasks that can start only when their `parents` are completed.
|
||||
We will encounter similar flows later on when discussing band structure calculations with AbiPy.
|
||||
|
||||
Once the flow is completed, you can analyze the results with
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.analyze(flow)
|
||||
|
||||
This call reads the output files, retrieves the data, and produces a matplotlib plot.
|
||||
|
||||
Finally, once you have completed this lesson you can exit ipython with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
exit
|
||||
|
||||
Note that in your working directory there is a new sub-directory (flow_lesson_Si_kpoint_convergence)
|
||||
containing all the input and output files produced by the flow.
|
||||
Have a look at these folders and the files that are in them.
|
||||
Hint: you can use the `ls` command inside ipython to list files and directories.
|
||||
You can even open a file directly within ipython with the command: `!vi filename`
|
||||
|
||||
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
As an exercise, you can start this lesson again but instead
|
||||
of performing the convergence study for silicon, you could perform a
|
||||
similar analysis for a metal.
|
||||
|
||||
Use:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
flow = lesson.make_ngkpt_flow(structure_file=lesson.abidata.cif_file('al.cif'), metal=True)
|
||||
|
||||
to generate a flow for aluminum.
|
||||
|
||||
Be careful however, aluminum is a metal and the default
|
||||
parameters for occopt and tsmear are for semiconductors. The
|
||||
keyword argument 'metal' fixes this. (you could also see what
|
||||
happens if you don't put this flag :-) ) Look at the inputs to
|
||||
see what has been changed and study the description of these
|
||||
variables using lesson.docvar.
|
||||
|
||||
If you have time left, it is also a good exercise to open the
|
||||
python file that contains this lesson and study the internal implementation.
|
||||
You can get a copy of the file with:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.get_local_copy()
|
||||
|
||||
Try to find what to change the set of k-point meshes used in the convergence studies.
|
||||
|
||||
Next
|
||||
----
|
||||
|
||||
A logical next lesson would be lesson_ecut_convergence
|
||||
"""
|
||||
|
||||
_commandline_lesson_ = """
|
||||
For a more detailed description of the variables, you are invited to consult the abinit documentation.
|
||||
The full description, directly from the official abinit docs, is available via the shell command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abidoc.py man inputvariable
|
||||
|
||||
that prints the official description of inputvariable.
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
|
||||
In the generation of this lesson by the python script all the input files have been generated automatically.
|
||||
The input files have been organized in a workdir "flow_lesson_Si_kpoint_convergence".
|
||||
Inside this directory, you'll find a single work, w0, with four tasks, t0-t1-t2-t3.
|
||||
Have a look at the input files, run.abi, of the four tasks to see what is different.
|
||||
|
||||
You'll see that also the files file and the jobs submission script have been generated.
|
||||
In the job scripts you'll see that the jobs are prepared to run just on the front end.
|
||||
|
||||
You'll also see that the files file has been created as well.
|
||||
|
||||
To perform the k-point convergence study execute, abinit with the four input sets.
|
||||
|
||||
Once the calculations are ready, you'll see three important output files.
|
||||
|
||||
* run.out
|
||||
* run.log
|
||||
* run.err
|
||||
|
||||
The main summary of the calculation can be found in the .out file, we'll go there soon :-). The .err file should be
|
||||
empty. If it's not something went wrong. If something went wrong read the .err. file. The .log file contains extensive
|
||||
information on you calculation that could help to find out what went wrong in the case of errors. Especially there are
|
||||
three types of messages that could help
|
||||
|
||||
* COMMENT
|
||||
* WARNING
|
||||
* ERROR
|
||||
|
||||
In case of an error message abinit stopped the execution by itself, because of that error.
|
||||
|
||||
Now the .out file. Some interesting keywords to look for:
|
||||
|
||||
* Symmetries
|
||||
* Citation for XC functional:
|
||||
* ETOT (the total energies during the electronic structure convergence)
|
||||
* Eigenvalues
|
||||
* Etotal (the total energy of an ionic step)
|
||||
|
||||
Obviously there is much more.
|
||||
|
||||
Collect the total energies of the four calculations and plot them as a function of the number of k-points in the
|
||||
calculation.
|
||||
|
||||
Alternative to execution of the manual execution the calculations can also be executed using the abipy scheduler.
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abirun.py flow_lesson_Si_kpoint_convergence scheduler
|
||||
|
||||
"""
|
||||
import os
|
||||
import abipy.abilab as abilab
|
||||
import abipy.data as abidata
|
||||
import abipy.flowtk as flowtk
|
||||
from abipy.lessons.core import BaseLesson, get_pseudos
|
||||
|
||||
|
||||
def make_ngkpt_flow(ngkpt_list=((2, 2, 2), (4, 4, 4), (6, 6, 6), (8, 8, 8)), structure_file=None, metal=False):
|
||||
"""
|
||||
A `factory function` (a function that returns an instance of the class defined above. If no specific system is
|
||||
specified, structure_file=None, an flow for silicon in constructed and returned.
|
||||
"""
|
||||
# Defining the structure and adding the appropriate pseudo potentials
|
||||
if structure_file is None:
|
||||
multi = abilab.MultiDataset(structure=abidata.cif_file("si.cif"),
|
||||
pseudos=abidata.pseudos("14si.pspnc"), ndtset=len(ngkpt_list))
|
||||
workdir = "flow_lesson_Si_kpoint_convergence"
|
||||
else:
|
||||
structure = abilab.Structure.from_file(structure_file)
|
||||
pseudos = get_pseudos(structure)
|
||||
multi = abilab.MultiDataset(structure, pseudos=pseudos, ndtset=len(ngkpt_list))
|
||||
workdir = "flow_lesson_" + structure.composition.reduced_formula + "_kpoint_convergence"
|
||||
|
||||
# Add mnemonics to input file.
|
||||
multi.set_mnemonics(True)
|
||||
|
||||
# Global variables
|
||||
multi.set_vars(ecut=10, tolvrs=1e-9)
|
||||
|
||||
if metal:
|
||||
multi.set_vars(occopt=7, tsmear=0.04)
|
||||
|
||||
# Specific variables for the different calculations
|
||||
for i, ngkpt in enumerate(ngkpt_list):
|
||||
multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0])
|
||||
|
||||
return flowtk.Flow.from_inputs(workdir=workdir, inputs=multi.split_datasets())
|
||||
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return __doc__ + _ipython_lesson_
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return __doc__ + _commandline_lesson_
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return os.path.abspath(__file__).replace(".pyc", ".py")
|
||||
|
||||
@staticmethod
|
||||
def make_ngkpt_flow(**kwargs):
|
||||
return make_ngkpt_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze(my_flow, **kwargs):
|
||||
with abilab.abirobot(my_flow, "GSR") as robot:
|
||||
data = robot.get_dataframe()
|
||||
import matplotlib.pyplot as plt
|
||||
ax = data.plot(x="nkpt", y="energy", title="Total energy vs nkpts",
|
||||
legend=False, style="b-o")
|
||||
ax.set_xlabel('Number of k-points')
|
||||
ax.set_ylabel('Total Energy [eV]')
|
||||
return plt.show(**kwargs)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
lesson = Lesson()
|
||||
flow = lesson.make_ngkpt_flow()
|
||||
flow.build_and_pickle_dump()
|
||||
lesson.setup()
|
|
@ -1,83 +0,0 @@
|
|||
.TH Relaxation "" "" "of the unit cell with two different techniques"
|
||||
.SH Background
|
||||
.PP
|
||||
In this lesson we discuss two different methods to find the equilibrium
|
||||
structure of a system.
|
||||
In the first method, we use the GS part of Abinit to calculate the total
|
||||
energy of silicon for different volumes and then we fit the energy vs
|
||||
the volume with a model for the equation of state (EOS).
|
||||
The fit provides the optimal volume (i.e.
|
||||
the volume for which the total energy is minimal), as well as the bulk
|
||||
modulus (the \[aq]compressibility\[aq] of the system).
|
||||
Note that this approach is only applicable to isotropic materials
|
||||
without any degree of freedom for the atomic positions.
|
||||
Indeed, the equation of state is obtained by performing a homogeneous
|
||||
compressions/dilatation of the initial Bravais lattice while keeping the
|
||||
atoms fixed in the initial high\-symmetry positions.
|
||||
.PP
|
||||
In the second example, we find the equilibrium configuration of GaN.
|
||||
In this case, the approach used for computing the EOS of silicon is not
|
||||
applicable because, one should optimize both the lattice parameters as
|
||||
well the distance between Ga and N.
|
||||
For this reason, we employ the relaxation algorithms implemented in
|
||||
Abinit (ionmov and optcell) in which the forces and the stresses
|
||||
obtained at the end of the SCF cycle are used to find the minimum energy
|
||||
configuration.
|
||||
.SH The related abinit variables
|
||||
.RS
|
||||
.IP \[bu] 2
|
||||
ionmov
|
||||
.IP \[bu] 2
|
||||
optcell
|
||||
.IP \[bu] 2
|
||||
dilatmx
|
||||
.IP \[bu] 2
|
||||
ecutsm
|
||||
.IP \[bu] 2
|
||||
ntime
|
||||
.IP \[bu] 2
|
||||
tolmxf
|
||||
.IP \[bu] 2
|
||||
tolrff
|
||||
.RE
|
||||
.PP
|
||||
The full description of the variables, directly from the abinit
|
||||
documentation is available via the shell command:
|
||||
.RS
|
||||
.IP
|
||||
.nf
|
||||
\f[C]
|
||||
abidoc.py\ man\ inputvariable
|
||||
\f[]
|
||||
.fi
|
||||
.RE
|
||||
.PP
|
||||
that prints the official description of inputvariable.
|
||||
.PP
|
||||
As in the previous lessons, executing the python script creates the
|
||||
folder structure with the input files for this lesson.
|
||||
.PP
|
||||
For the flow_si_relax folder, look in particular to the changes in the
|
||||
unit cell (rprim) in the input files and the corresponding change in the
|
||||
unit cell volume (ucvol), total energy (etotal) and stresses (strten) in
|
||||
the output file.
|
||||
For the flow_gan_relax, observe in the output files how the automatic
|
||||
relaxation takes place.
|
||||
At each step of the relaxation, a full SCF\-cycle is performed and
|
||||
forces and the stress are computed.
|
||||
The ions are then moved according to the forces and a new SCF\-cycle is
|
||||
started.
|
||||
The procedure is interated until convergence is achieved.
|
||||
This is the reason why there are two stopping criteria for structural
|
||||
relaxation: tolrff or tolvrs are used for the SCF cycle whereas tolmxf
|
||||
govers the relaxation algorithm.
|
||||
.SH Exercises
|
||||
.PP
|
||||
Edit the input files to run the same jobs with different values of ecut.
|
||||
.PP
|
||||
You can also try to change the stopping criterion to see if this affects
|
||||
the final results.
|
||||
.PP
|
||||
Finally, try to generate the input file for silicon, and try to guess
|
||||
why setting the stopping criterion on the forces won\[aq]t work in this
|
||||
case!
|
|
@ -1,321 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
"""
|
||||
Relaxation of the unit cell with two different techniques
|
||||
=========================================================
|
||||
|
||||
Background
|
||||
----------
|
||||
|
||||
In this lesson we discuss two different methods to find the equilibrium structure of a system.
|
||||
In the first method, we use the GS part of Abinit to calculate the total energy of silicon for
|
||||
different volumes and then we fit the energy vs the volume with a model for the equation of state (EOS).
|
||||
The fit provides the optimal volume (i.e. the volume for which the total energy is minimal),
|
||||
as well as the bulk modulus (the 'compressibility' of the system).
|
||||
Note that this approach is only applicable to isotropic materials without any degree of freedom for the atomic positions.
|
||||
Indeed, the equation of state is obtained by performing a homogeneous compressions/dilatation of
|
||||
the initial Bravais lattice while keeping the atoms fixed in the initial high-symmetry positions.
|
||||
|
||||
In the second example, we find the equilibrium configuration of GaN.
|
||||
In this case, the approach used for computing the EOS of silicon is not applicable because,
|
||||
one should optimize both the lattice parameters as well the distance between Ga and N.
|
||||
For this reason, we employ the relaxation algorithms implemented in Abinit (`ionmov` and `optcell`)
|
||||
in which the forces and the stresses obtained at the end of the SCF cycle are used to find the minimum energy configuration.
|
||||
|
||||
The related abinit variables
|
||||
----------------------------
|
||||
|
||||
* ionmov
|
||||
* optcell
|
||||
* dilatmx
|
||||
* ecutsm
|
||||
* ntime
|
||||
* tolmxf
|
||||
* tolrff
|
||||
|
||||
"""
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
_ipython_lesson_ = """
|
||||
For a more detailed description of the variables, you are invited to consult the abinit documentation.
|
||||
The full description, directly from the official abinit docs, is available in ipython with the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
print(lesson.docvar("inputvariable"))
|
||||
|
||||
|
||||
Description of the lesson
|
||||
-------------------------
|
||||
|
||||
We will use two different AbiPy flows to find the equilibrium configuration.
|
||||
The first flow, si_flow, calculates the total energy of silicon at different volumes
|
||||
and computes the equation of state E(V).
|
||||
The other flow, gan_flow, uses Abinit to optimize all degrees of freedom (atomic positions
|
||||
and lattice vectors).
|
||||
|
||||
Executing the lesson
|
||||
--------------------
|
||||
|
||||
Start this lesson by importing it with the commands:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
from abipy.lessons.lesson_relaxation import Lesson
|
||||
lesson = Lesson()
|
||||
|
||||
As usual, you can reread this text using the command:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson
|
||||
|
||||
To build the flow for silicon, use
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
si_flow = lesson.make_eos_flow()
|
||||
|
||||
For Gallium Nitride, use
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
gan_flow = lesson.make_relax_flow()
|
||||
|
||||
To print the input files
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
si_flow.show_inputs()
|
||||
|
||||
Start the flow with the scheduler and wait for completion.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
si_flow.make_scheduler().start()
|
||||
|
||||
To analyze the results.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
# For Silicon
|
||||
lesson.analyze_eos_flow(si_flow)
|
||||
|
||||
# For Gallium Nitride, use
|
||||
lesson.analyze_eos_flow(gan_flow)
|
||||
|
||||
In the case of silicon, python will show a fit of the total energy vs the
|
||||
volume of the unit cell. The minimum of this curve is the equilibrium
|
||||
volume. From this fit, we can also obtain the bulk modulus.
|
||||
Note that this approach is only applicable to isotropic materials since the
|
||||
equation of state has been obtained by performing
|
||||
a homogeneous compressions/dilatation of the initial Bravais lattice.
|
||||
|
||||
Try to compare the results with these experimental results:
|
||||
Volume of the unit cell of silicon: 40.05 A^3 [NSM]
|
||||
Bulk modulus: 98 GPa [NSM]
|
||||
|
||||
In the case of gallium nitride, you will observe a change of the equilibrium
|
||||
parameters with respect to the k-point mesh.
|
||||
|
||||
Try to compare the results with these experimental results:
|
||||
|
||||
* Volume of the unit cell of GaN: 45.73 A^3 [Schulz & Thiemann 1977]
|
||||
* Lattice parameters of GaN: a = 3.190 A, c = 5.189 A [Schulz & Thiemann 1977]
|
||||
* Vertical distance between Ga and N : about 0.377 * c [ Schulz & Thiemann, 1977]
|
||||
|
||||
Of course you will need to converge your results with respect to the k-point sampling and the
|
||||
cutoff energy ecut.
|
||||
|
||||
Note the we are using pseudopotentials generated with the GGA which tends to
|
||||
overestimate the lattice parameters.
|
||||
If you use LDA-type pseudopotentials, you will observe that LDA tends to underestimate the parameters.
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
As an exercise you can now try to get the equilibrium unit cell of silicon automatically using abinit.
|
||||
You can use the code for the relaxation of GaN as template.
|
||||
First download a local copy of the python script.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
lesson.get_local_copy()
|
||||
|
||||
and have a look at the code in make_relax_gan_flow().
|
||||
Try to do the same with 'si.cif' file instead of 'gan.cif'
|
||||
|
||||
Pay attention to the fact that for silicon, you cannot use tolrff
|
||||
to stop your self-consistent cycle.
|
||||
Silicon has no internal degree of freedom, the forces are zero by symmetry.
|
||||
and hence the tolrff criterion makes no sense.
|
||||
|
||||
As a second exercise, you can try to converge the results for silicon with respect
|
||||
to the k-point sampling and ecut.
|
||||
Compare the converged results with experimental data.
|
||||
|
||||
Next
|
||||
----
|
||||
|
||||
A logical next lesson would be lesson_dos_bands
|
||||
"""
|
||||
|
||||
|
||||
_commandline_lesson_ = """
|
||||
The full description of the variables, directly from the abinit documentation is available via the shell command:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
abidoc.py man inputvariable
|
||||
|
||||
that prints the official description of `inputvariable`.
|
||||
|
||||
As in the previous lessons, executing the python script creates the folder structure with the input files for this
|
||||
lesson.
|
||||
|
||||
For the flow_si_relax folder, look in particular to the changes in the unit cell (rprim) in the input files and the
|
||||
corresponding change in the unit cell volume (ucvol), total energy (etotal) and stresses (strten) in the output file.
|
||||
For the flow_gan_relax, observe in the output files how the automatic relaxation takes place.
|
||||
At each step of the relaxation, a full SCF-cycle is performed and forces and the stress are computed.
|
||||
The ions are then moved according to the forces and a new SCF-cycle is started.
|
||||
The procedure is interated until convergence is achieved.
|
||||
This is the reason why there are two stopping criteria for structural relaxation:
|
||||
tolrff or tolvrs are used for the SCF cycle whereas tolmxf govers the relaxation algorithm.
|
||||
|
||||
Exercises
|
||||
---------
|
||||
|
||||
Edit the input files to run the same jobs with different values of ecut.
|
||||
|
||||
You can also try to change the stopping criterion to see if this affects the final results.
|
||||
|
||||
Finally, try to generate the input file for silicon, and try to guess why setting the stopping
|
||||
criterion on the forces won't work in this case!
|
||||
"""
|
||||
|
||||
import os
|
||||
import numpy as np
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
import abipy.data as abidata
|
||||
|
||||
from pymatgen.analysis.eos import EOS
|
||||
from abipy.core import Structure
|
||||
from abipy.lessons.core import BaseLesson, get_pseudos
|
||||
|
||||
|
||||
def make_relax_flow(structure_file=None):
|
||||
"""
|
||||
Build and return a flow that perform a structural relaxation for different k-point samplings.
|
||||
"""
|
||||
ngkpt_list = [[3, 3, 2], [6, 6, 4], [8, 8, 6]]
|
||||
|
||||
if structure_file is None:
|
||||
structure = abilab.Structure.from_file(abidata.cif_file("gan2.cif"))
|
||||
else:
|
||||
structure = abilab.Structure.from_file(structure_file)
|
||||
|
||||
multi = abilab.MultiDataset(structure=structure, pseudos=get_pseudos(structure), ndtset=len(ngkpt_list))
|
||||
|
||||
# Add mnemonics to input file.
|
||||
multi.set_mnemonics(True)
|
||||
|
||||
# Global variables
|
||||
multi.set_vars(
|
||||
ecut=20,
|
||||
tolrff=5.0e-2,
|
||||
nstep=30,
|
||||
optcell=2,
|
||||
ionmov=3,
|
||||
ntime=50,
|
||||
dilatmx=1.05,
|
||||
ecutsm=0.5,
|
||||
tolmxf=5.0e-5,
|
||||
)
|
||||
|
||||
for i, ngkpt in enumerate(ngkpt_list):
|
||||
multi[i].set_kmesh(ngkpt=ngkpt, shiftk=[0, 0, 0])
|
||||
|
||||
return flowtk.Flow.from_inputs("flow_gan_relax", inputs=multi.split_datasets(), task_class=flowtk.RelaxTask)
|
||||
|
||||
|
||||
def make_eos_flow(structure_file=None):
|
||||
"""
|
||||
Build and return a Flow to compute the equation of state
|
||||
of an isotropic material for different k-point samplings.
|
||||
"""
|
||||
scale_volumes = np.arange(94, 108, 2) / 100.
|
||||
|
||||
if structure_file is None:
|
||||
structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
|
||||
else:
|
||||
structure = abilab.Structure.from_file(structure_file)
|
||||
|
||||
multi = abilab.MultiDataset(structure=structure, pseudos=get_pseudos(structure), ndtset=len(scale_volumes))
|
||||
|
||||
# Global variables
|
||||
multi.set_vars(
|
||||
ecut=16,
|
||||
tolvrs=1e-16
|
||||
)
|
||||
|
||||
multi.set_kmesh(ngkpt=[4, 4, 4], shiftk=[[0.5, 0.5, 0.5], [0.5, 0.0, 0.0], [0.0, 0.5, 0.0], [0.0, 0.0, 0.5]])
|
||||
|
||||
for idt, scal_vol in enumerate(scale_volumes):
|
||||
new_lattice = structure.lattice.scale(structure.volume*scal_vol)
|
||||
|
||||
new_structure = Structure(new_lattice, structure.species, structure.frac_coords)
|
||||
|
||||
multi[idt].set_structure(new_structure)
|
||||
|
||||
eos_flow = flowtk.Flow.from_inputs("flow_si_relax", inputs=multi.split_datasets())
|
||||
eos_flow.volumes = structure.volume * scale_volumes
|
||||
return eos_flow
|
||||
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return __doc__ + _ipython_lesson_
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return __doc__ + _commandline_lesson_
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return os.path.abspath(__file__).replace(".pyc", ".py")
|
||||
|
||||
@staticmethod
|
||||
def make_eos_flow(**kwargs):
|
||||
return make_eos_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze_eos_flow(flow, **kwargs):
|
||||
work = flow[0]
|
||||
etotals = work.read_etotals(unit="eV")
|
||||
eos_fit = EOS(eos_name="birch_murnaghan").fit(flow.volumes, etotals)
|
||||
return eos_fit.plot(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def make_relax_flow(**kwargs):
|
||||
return make_relax_flow(**kwargs)
|
||||
|
||||
@staticmethod
|
||||
def analyze_relax_flow(flow, **kwargs):
|
||||
def get_dist(gsrfile):
|
||||
struct = gsrfile.structure
|
||||
red_dist = struct.frac_coords[2][2] - struct.frac_coords[0][2]
|
||||
return 'u', red_dist
|
||||
|
||||
with abilab.GsrRobot.open(flow) as robot:
|
||||
data = robot.get_dataframe(funcs=get_dist)
|
||||
return robot.pairplot(data, x_vars="nkpt", y_vars=["a", "c", "volume", "u"])
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
lesson = Lesson()
|
||||
flow = lesson.make_eos_flow()
|
||||
flow.build_and_pickle_dump()
|
||||
flow = lesson.make_relax_flow()
|
||||
lesson.setup()
|
|
@ -1,177 +0,0 @@
|
|||
#!/usr/bin/env python
|
||||
from __future__ import division, print_function, unicode_literals, absolute_import
|
||||
|
||||
import abipy.abilab as abilab
|
||||
import abipy.flowtk as flowtk
|
||||
import abipy.data as abidata
|
||||
|
||||
|
||||
def gs_input(nsppol):
|
||||
# Fe normal bcc structure for test of a ferromagnetic calculation
|
||||
# The first dataset is without magnetization for comparison
|
||||
structure = abilab.Structure.from_abivars(dict(
|
||||
natom=1,
|
||||
ntypat=1,
|
||||
typat=1,
|
||||
znucl=26,
|
||||
acell=3*[5.42],
|
||||
rprim=[-0.5, 0.5, 0.5,
|
||||
0.5, -0.5, 0.5,
|
||||
0.5, 0.5, -0.5],
|
||||
xred=[0.0, 0.0, 0.0])
|
||||
)
|
||||
inp = abilab.AbinitInput(structure, pseudos=abidata.pseudos("26fe.pspnc"))
|
||||
|
||||
inp.set_kmesh(ngkpt=[4, 4, 4], shiftk=[0.5, 0.5, 0.5])
|
||||
|
||||
# Optimization of the lattice parameters
|
||||
inp.set_vars(
|
||||
nsppol=nsppol,
|
||||
ecut=18,
|
||||
nband=8,
|
||||
occopt=3,
|
||||
tsmear=0.01,
|
||||
toldfe=1e-6,
|
||||
nstep=50,
|
||||
)
|
||||
|
||||
if nsppol == 2:
|
||||
inp.set_vars(spinat=[0.0, 0.0, 4.0])
|
||||
|
||||
return inp
|
||||
|
||||
|
||||
def afm_input():
|
||||
# Fe fcc structure with two atoms per unit cell for test of antiferromagnetic
|
||||
# This is the simplest fcc structure compatible with a X point spiral
|
||||
structure = abilab.Structure.from_abivars(dict(
|
||||
natom=2,
|
||||
ntypat=1,
|
||||
typat=[1, 1],
|
||||
znucl=26,
|
||||
acell=3*[6.60],
|
||||
rprim=[0.5, -0.5, 0.0,
|
||||
0.5, 0.5, 0.0,
|
||||
0.0, 0.0, 1.0],
|
||||
xred=[0.0, 0.0, 0.0,
|
||||
0.5, 0.0, 0.5],
|
||||
))
|
||||
inp = abilab.AbinitInput(structure=structure, pseudos=abidata.pseudos("26fe.pspnc"))
|
||||
|
||||
inp.set_kmesh(ngkpt=[6, 6, 4], shiftk=[0.5, 0.5, 0.5])
|
||||
|
||||
# Antiferromagnetic order
|
||||
inp.set_vars(
|
||||
nsppol=1,
|
||||
nspden=2,
|
||||
spinat=[0.0, 0.0, 4.0,
|
||||
0.0, 0.0, -4.0],
|
||||
ecut=18,
|
||||
nband=16,
|
||||
occopt=3,
|
||||
tsmear=0.01,
|
||||
tolwfr=1e-7,
|
||||
nstep=70,
|
||||
)
|
||||
|
||||
return inp
|
||||
|
||||
|
||||
def gs_flow():
|
||||
inputs = [gs_input(nsppol) for nsppol in [1, 2]]
|
||||
flow = flowtk.Flow.from_inputs(workdir="flow_spin", inputs=inputs)
|
||||
flow.make_scheduler().start()
|
||||
|
||||
with abilab.abirobot(flow, "GSR") as robot:
|
||||
data = robot.get_dataframe()
|
||||
print(data)
|
||||
robot.pairplot(x_vars="nsppol", y_vars=["energy", "a", "volume", "pressure"])
|
||||
|
||||
#gstask_nospin, gstask_spin = flow[0][0], flow[0][1]
|
||||
#data = abilab.PrettyTable(["property", "unpolarized", "polarized"])
|
||||
#with gstask_nospin.open_gsr() as gsr_nospin, gstask_spin.open_gsr() as gsr_spin:
|
||||
# properties = ["energy", "pressure", "magnetization", "nelect_updown"]
|
||||
# for p in properties:
|
||||
# row = [p, getattr(gsr_nospin, p), getattr(gsr_spin, p)]
|
||||
# data.add_row(row)
|
||||
|
||||
# plotter = abilab.ElectronDosPlotter()
|
||||
# plotter.add_edos_from_file(gsr_spin.filepath, label="spin")
|
||||
# plotter.add_edos_from_file(gsr_nospin.filepath, label="nospin")
|
||||
# plotter.plot()
|
||||
|
||||
# #gsr_spin.plot_ebands()
|
||||
# #gsr_nospin.plot_ebands_with_dos()
|
||||
# #plotter = abilab.ElectronBandsPlotter()
|
||||
# #plotter.add_ebands_from_file(gsr_spin.filepath, label="spin")
|
||||
# #plotter.plot()
|
||||
# #plotter = abilab.GSR_Plotter(gsr_nospin.filepath, gsr_spin.filepath)
|
||||
# #plotter.add_ebands_from_file(gsr_nospin.filepath, label="nospin")
|
||||
#print(data)
|
||||
|
||||
|
||||
def afm_flow():
|
||||
flow = flowtk.Flow.from_inputs(workdir="flow_afm", inputs=afm_input())
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
with flow[0][0].open_gsr() as gsr:
|
||||
print("Energy: ", gsr.energy.to("Ha"))
|
||||
print("Magnetization: ",gsr.magnetization)
|
||||
|
||||
|
||||
def tantalum_gsinput(nspinor=2):
|
||||
# Single Ta atom in a big box (BCC), treated with spin-orbit coupling.
|
||||
structure = abilab.Structure.from_abivars(
|
||||
natom=1,
|
||||
ntypat=1,
|
||||
typat=[1],
|
||||
znucl=73,
|
||||
acell=3*[15.0],
|
||||
rprim=[ 0.5, 0.5, -0.5,
|
||||
-0.5, 0.5, 0.5,
|
||||
0.5, -0.5, 0.5],
|
||||
xred=[0.0, 0.0, 0.0]
|
||||
)
|
||||
inp = abilab.AbinitInput(structure=structure, pseudos=abidata.pseudos("73ta.hghsc"))
|
||||
|
||||
inp.set_kmesh(ngkpt=[1, 1, 1], shiftk=[0.0, 0.0, 0.0])
|
||||
|
||||
inp.set_vars(
|
||||
nspinor=nspinor,
|
||||
ecut=10,
|
||||
ixc=2,
|
||||
istwfk=1,
|
||||
intxc=1,
|
||||
nband=26,
|
||||
occopt=7,
|
||||
tsmear=0.01,
|
||||
toldfe=1e-7,
|
||||
nstep=70,
|
||||
)
|
||||
|
||||
print(inp)
|
||||
return inp
|
||||
|
||||
|
||||
def tantalum_flow():
|
||||
inputs = [tantalum_gsinput(nspinor) for nspinor in [1, 2]]
|
||||
flow = abilab.Flow.from_inputs(workdir="flow_tantalum", inputs=inputs)
|
||||
|
||||
flow.make_scheduler().start()
|
||||
|
||||
with abilab.GsrRobot.open(flow) as robot:
|
||||
data = robot.get_dataframe()
|
||||
print(data)
|
||||
robot.pairplot(x_vars="nspinor", y_vars=["energy", "magnetization", "pressure"])
|
||||
|
||||
#for task in flow.iflat_tasks():
|
||||
# with task.open_gsr() as gsr:
|
||||
# print("Energy: ", gsr.energy.to("Ha"))
|
||||
# print("Magnetization: ",gsr.magnetization)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
gs_flow()
|
||||
#afm_flow()
|
||||
#tantalum_flow()
|
|
@ -1,57 +0,0 @@
|
|||
from __future__ import unicode_literals, division, print_function
|
||||
|
||||
import os
|
||||
import copy
|
||||
import abipy.data as abidata
|
||||
import abipy.abilab as abilab
|
||||
|
||||
from pymatgen.io.abinit.pseudos import NcAbinitPseudo
|
||||
from abipy.core.testing import AbipyTest
|
||||
from abipy.lessons.core import get_pseudos, BaseLesson
|
||||
|
||||
|
||||
|
||||
class CoreTest(AbipyTest):
|
||||
"""
|
||||
Testing helper functions in core
|
||||
"""
|
||||
|
||||
def test_get_pseudo(self):
|
||||
"""
|
||||
Testing the get_pseudo method
|
||||
"""
|
||||
structure = abilab.Structure.from_file(abidata.cif_file("si.cif"))
|
||||
pseudos = get_pseudos(structure)
|
||||
assert len(pseudos) == 1
|
||||
assert isinstance(pseudos[0], NcAbinitPseudo)
|
||||
|
||||
def test_base_lesson(self):
|
||||
# FIXME: This is broken
|
||||
#from abipy.lessons import help
|
||||
#assert help()
|
||||
|
||||
a, c, p = "a", "c", "p.py"
|
||||
|
||||
class Lesson(BaseLesson):
|
||||
@property
|
||||
def abipy_string(self):
|
||||
return copy.copy(a)
|
||||
|
||||
@property
|
||||
def comline_string(self):
|
||||
return copy.copy(c)
|
||||
|
||||
@property
|
||||
def pyfile(self):
|
||||
return copy.copy(p)
|
||||
|
||||
lesson = Lesson()
|
||||
lesson.abidata.cif_file("si.cif")
|
||||
|
||||
assert lesson.abipy_string == a
|
||||
assert lesson.comline_string == c
|
||||
assert lesson.pyfile == p
|
||||
assert lesson.manpath.replace("u'", "'") == p.replace('py','man')
|
||||
assert len(str(lesson.docvar('ecut'))) > 4
|
||||
lesson._gen_manfile()
|
||||
os.remove(p.replace('py', 'man'))
|
|
@ -1,103 +0,0 @@
|
|||
"""Tests for lessons"""
|
||||
from __future__ import print_function, division
|
||||
|
||||
import os
|
||||
|
||||
from abipy.core.testing import *
|
||||
|
||||
|
||||
class TestLessons(AbipyTest):
|
||||
"""Unit tests for lessons."""
|
||||
|
||||
@staticmethod
|
||||
def assert_lesson_object(lesson):
|
||||
"""Helper function to test `Lesson` protocol."""
|
||||
assert len(str(lesson))
|
||||
assert lesson.abipy_string + " "
|
||||
assert lesson.comline_string + " "
|
||||
assert os.path.exists(lesson.pyfile)
|
||||
|
||||
def test_lesson_base1(self):
|
||||
"""Testing lesson_base1."""
|
||||
from abipy.lessons.lesson_base1 import build_flow, analyze_flow
|
||||
#self.assert_lesson_object(Lesson())
|
||||
flow = build_flow()
|
||||
flow.make_scheduler().start()
|
||||
analyze_flow(flow)
|
||||
flow.rmtree()
|
||||
|
||||
def test_lesson_bse(self):
|
||||
"""Testing lesson_bse."""
|
||||
from abipy.lessons.lesson_bse import make_scf_nscf_bse_inputs
|
||||
|
||||
scf_input, nscf_input, bse_input = make_scf_nscf_bse_inputs(
|
||||
ngkpt=(6, 6, 6), ecut=6, ecuteps=3, mdf_epsinf=12.0, mbpt_sciss="0.8 eV")
|
||||
|
||||
bse_input.abivalidate()
|
||||
|
||||
def test_lesson_dfpt(self):
|
||||
"""Testing lesson_dfpt."""
|
||||
from abipy.lessons.lesson_dfpt import make_scf_input
|
||||
scf_input = make_scf_input(ecut=2, ngkpt=(4, 4, 4))
|
||||
scf_input.abivalidate()
|
||||
|
||||
def test_lesson_dos_bands(self):
|
||||
"""Testing lesson_dos_bands."""
|
||||
from abipy.lessons.lesson_dos_bands import Lesson
|
||||
lesson = Lesson()
|
||||
self.assert_lesson_object(lesson)
|
||||
|
||||
flow = lesson.make_flow()
|
||||
flow.make_scheduler().start()
|
||||
#flow.build_and_pickle_dump()
|
||||
#lesson.setup()
|
||||
#lesson.analyze(flow)
|
||||
flow.rmtree()
|
||||
|
||||
def test_lesson_ecut_convergence(self):
|
||||
"""Testing lesson_ecut_convergence."""
|
||||
from abipy.lessons.lesson_ecut_convergence import Lesson
|
||||
lesson = Lesson()
|
||||
self.assert_lesson_object(lesson)
|
||||
|
||||
flow = lesson.make_ecut_flow()
|
||||
flow.make_scheduler().start()
|
||||
#flow.build_and_pickle_dump()
|
||||
#lesson.setup()
|
||||
#lesson.analyze(flow)
|
||||
flow.rmtree()
|
||||
|
||||
def test_lesson_g0w0(self):
|
||||
"""Testing lesson_g0w0."""
|
||||
from abipy.lessons.lesson_g0w0 import Lesson
|
||||
lesson = Lesson()
|
||||
self.assert_lesson_object(lesson)
|
||||
|
||||
flow = lesson.make_flow()
|
||||
#flow.build_and_pickle_dump()
|
||||
flow.make_scheduler().start()
|
||||
#lesson.setup()
|
||||
#lesson.analyze(flow)
|
||||
flow.rmtree()
|
||||
|
||||
def test_lesson_kpoint_convergence(self):
|
||||
"""Testing lesson_kpoint_convergence."""
|
||||
from abipy.lessons.lesson_kpoint_convergence import Lesson
|
||||
lesson = Lesson()
|
||||
self.assert_lesson_object(lesson)
|
||||
|
||||
flow = lesson.make_ngkpt_flow()
|
||||
flow.make_scheduler().start()
|
||||
flow.rmtree()
|
||||
|
||||
def test_lesson_relaxation(self):
|
||||
"""Testing lesson_relaxation."""
|
||||
from abipy.lessons.lesson_relaxation import Lesson
|
||||
lesson = Lesson()
|
||||
self.assert_lesson_object(lesson)
|
||||
flow = Lesson.make_eos_flow()
|
||||
flow = Lesson.make_relax_flow()
|
||||
|
||||
#def test_lesson_spin(self):
|
||||
# """Testing lesson_spin."""
|
||||
# from abipy.lessons.lesson_spin import gs_flow
|
26
setup.py
26
setup.py
|
@ -16,13 +16,6 @@ if sys.version[0:3] < '2.7':
|
|||
sys.stderr.write("abipy requires Python version 2.7 or above. Exiting.")
|
||||
sys.exit(1)
|
||||
|
||||
# Install ipython with notebook support.
|
||||
with_ipython = False
|
||||
#with_ipython = True
|
||||
#if '--with-ipython' in sys.argv:
|
||||
# with_ipython = True
|
||||
# sys.argv.remove('--with-ipython')
|
||||
|
||||
#with_cython = True
|
||||
#try:
|
||||
# from Cython.Distutils import build_ext
|
||||
|
@ -133,7 +126,6 @@ def find_package_data():
|
|||
],
|
||||
'abipy.htc': ["*.json"],
|
||||
'abipy.gui.awx' : ['images/*'],
|
||||
'abipy.lessons': ["*.man"],
|
||||
}
|
||||
|
||||
#package_data.update(ref_files)
|
||||
|
@ -205,13 +197,6 @@ install_requires = [
|
|||
"seaborn",
|
||||
]
|
||||
|
||||
#if with_ipython:
|
||||
# install_requires += [
|
||||
# "ipython",
|
||||
# "jupyter",
|
||||
# "nbformat",
|
||||
# ]
|
||||
|
||||
#if with_cython:
|
||||
# install_requires += [
|
||||
# "cython",
|
||||
|
@ -268,17 +253,6 @@ Please read the following if you are about to use abipy for the first time:
|
|||
in ~/.abinit/abipy or in the working directory in which you execute the flow.
|
||||
Examples are provided in abipy/data/managers
|
||||
|
||||
[2]
|
||||
If you are completely new to abipy you may want to start from the abipy lessons.
|
||||
The simplest way is to move to an empty directory, start an ipython session and type:
|
||||
|
||||
In [1]: from abipy.lessons.lesson_kpoint_convergence import Lesson()
|
||||
|
||||
followed by:
|
||||
|
||||
In [2]: Lesson()
|
||||
|
||||
This will print the lessons documentation with further instructions.
|
||||
Have fun!
|
||||
""")
|
||||
|
||||
|
|
Loading…
Reference in New Issue