[1]:
# useful to autoreload the module without restarting the kernel
%load_ext autoreload
%autoreload 2
[5]:
from mppi import InputFiles as I
Tutorial for the PwInput class
This tutorial describes the main features and the usage of the PwInput class that enables to create and manage the input files for the QuantumESPRESSO computations
Setting up an input from scratch
Create an empty input object from scratch
[6]:
inp = I.PwInput()
inp
[6]:
{'control': {},
'system': {},
'electrons': {},
'ions': {},
'cell': {},
'atomic_species': {},
'atomic_positions': {},
'kpoints': {},
'cell_parameters': {}}
The input object can be initialized passing arguments in the constuctor both using the kwargs syntax and/or passing a dictionary
[7]:
inp = I.PwInput(control = {'calculation' : 'scf'})
inp
[7]:
{'control': {'calculation': 'scf'},
'system': {},
'electrons': {},
'ions': {},
'cell': {},
'atomic_species': {},
'atomic_positions': {},
'kpoints': {},
'cell_parameters': {}}
[8]:
imp_dict = {'system' : {'ntyp' : 1}}
[9]:
inp = I.PwInput(control = {'calculation' : 'scf'}, **imp_dict)
inp
[9]:
{'control': {'calculation': 'scf'},
'system': {'ntyp': 1},
'electrons': {},
'ions': {},
'cell': {},
'atomic_species': {},
'atomic_positions': {},
'kpoints': {},
'cell_parameters': {}}
The attribute of the object can be updated using the standard procedure for python dictionaries, for instance
[10]:
inp['control'].update({'verbosity' : "'high'"})
inp
[10]:
{'control': {'calculation': 'scf', 'verbosity': "'high'"},
'system': {'ntyp': 1},
'electrons': {},
'ions': {},
'cell': {},
'atomic_species': {},
'atomic_positions': {},
'kpoints': {},
'cell_parameters': {}}
However it is more powerful to use the specific methods provided in the class (and other can be defined). For instance
[11]:
inp = I.PwInput()
[14]:
inp.set_scf()
inp.set_prefix('si_scf_pref')
inp.set_pseudo_dir(pseudo_dir='../pseudos')
# specific methods for the cell have still to be added
inp.set_lattice(ibrav=2,celldm1=10.3)
# Set the atoms type and positions
inp.add_atom('Si','Si.pbe-mt_fhi.UPF')
# add other atoms if needed, then set the number of atoms in the cell.
# This method sets the ntyp variable equal to the number of atoms added
# with the add_atom method
inp.set_atoms_number(2)
inp.set_atomic_positions([['Si',[0.,0.,0.,]],['Si',[0.25,0.25,0.25]]])
# Set the sampling of kpoints
inp.set_kpoints(type='automatic',points=[4,4,4])
inp
[14]:
{'control': {'calculation': "'scf'",
'verbosity': "'high'",
'prefix': "'si_scf_pref'",
'pseudo_dir': "'../pseudos'"},
'system': {'force_symmorphic': '.false.',
'ibrav': 2,
'celldm(1)': 10.3,
'ntyp': '1',
'nat': '2'},
'electrons': {'conv_thr': 1e-08, 'diago_full_acc': '.false.'},
'ions': {},
'cell': {},
'atomic_species': {'Si': ['1.0', 'Si.pbe-mt_fhi.UPF']},
'atomic_positions': {'type': 'alat',
'values': [['Si', [0.0, 0.0, 0.0]], ['Si', [0.25, 0.25, 0.25]]]},
'kpoints': {'type': 'automatic', 'values': ([4, 4, 4], [0.0, 0.0, 0.0])},
'cell_parameters': {}}
The usage of the methods is described in the documentation and can be easily accessed as follows
[15]:
inp.set_kpoints?
Signature: inp.set_kpoints(type='automatic', points=[1.0, 1.0, 1.0], shift=[0.0, 0.0, 0.0], path=[])
Docstring:
Define the sampling of the Brillouin zone.
Args:
type(str) : type of sampling (automatic, tpiba, tpiba_b,...)
points(list) : number of kpoints in the x,y,z directions. Used only is
type is automatic
shift(list) : shifts in the x,y,z directions. Used only is
type is automatic
path(list) : list with the structure:
[[k1x,k1y,k1z,w1],[k2x,k2y,k2z,w2],....]
Used only if type is not automatic
File: ~/Applications/MPPI/mppi/InputFiles/PwInput.py
Type: method
Once completed the input object can be converted to string with the correct format of the pw input files
[16]:
inp_tostring = inp.convert_string()
print(inp_tostring)
&control
calculation = 'scf'
prefix = 'si_scf_pref'
pseudo_dir = '../pseudos'
verbosity = 'high'
/&end
&system
celldm(1) = 10.3
force_symmorphic = .false.
ibrav = 2
nat = 2
ntyp = 1
/&end
&electrons
conv_thr = 1e-08
diago_full_acc = .false.
/&end
ATOMIC_SPECIES
Si 1.0 Si.pbe-mt_fhi.UPF
ATOMIC_POSITIONS { alat }
Si 0.0000000000 0.0000000000 0.0000000000
Si 0.2500000000 0.2500000000 0.2500000000
K_POINTS { automatic }
4 4 4 0 0 0
and finally it can be written on file
[17]:
inp.write('IO_files/pw_from-scratch.in')
Build and input starting from an existing file
Consider a second example in which the input is initialized from an existing input file
[18]:
inp = I.PwInput(file='IO_files/gaas_scf.in')
inp
[18]:
{'control': {'verbosity': "'high'",
'pseudo_dir': "'../pseudos'",
'calculation': "'scf'",
'prefix': "'ecut_40-k_4'"},
'system': {'occupations': "'fixed'",
'ibrav': '2',
'celldm(1)': '10.677',
'ntyp': '2',
'nat': '2',
'ecutwfc': '40'},
'electrons': {'conv_thr': '1e-08'},
'ions': {},
'cell': {},
'atomic_species': {'Ga': ['69.72', 'Ga_hamlu.fhi.UPF'],
'As': ['74.92', 'As_hamlu.fhi.UPF']},
'atomic_positions': {'type': 'crystal',
'values': [['Ga', [0.0, 0.0, 0.0]], ['As', [0.25, 0.25, 0.25]]]},
'kpoints': {'type': 'automatic',
'values': ([4.0, 4.0, 4.0], [0.0, 0.0, 0.0])},
'cell_parameters': {},
'file': 'IO_files/gaas_scf.in'}
The variables can be modified, for instance we can modify the input to perform a nscf computation with 12 bands and a given k-path
[19]:
G = [0.,0.,0.]
X = [1.,0.,0.]
L = [0.5,0.5,0.5]
W = [1.0,0.5,0.]
[20]:
from mppi.Utilities import build_kpath
kpath = build_kpath(G,X,L,W,numstep=30)
kpath
[20]:
[[0.0, 0.0, 0.0, 30],
[1.0, 0.0, 0.0, 30],
[0.5, 0.5, 0.5, 30],
[1.0, 0.5, 0.0, 0]]
[21]:
inp.set_nscf(12)
inp.set_kpoints(type='tpiba_b',path=kpath)
[22]:
inp_tostring = inp.convert_string()
print(inp_tostring)
&control
calculation = 'nscf'
prefix = 'ecut_40-k_4'
pseudo_dir = '../pseudos'
verbosity = 'high'
/&end
&system
celldm(1) = 10.677
ecutwfc = 40
force_symmorphic = .false.
ibrav = 2
nat = 2
nbnd = 12
ntyp = 2
occupations = 'fixed'
/&end
&electrons
conv_thr = 1e-08
diago_full_acc = .false.
/&end
ATOMIC_SPECIES
Ga 69.72 Ga_hamlu.fhi.UPF
As 74.92 As_hamlu.fhi.UPF
ATOMIC_POSITIONS { crystal }
Ga 0.0000000000 0.0000000000 0.0000000000
As 0.2500000000 0.2500000000 0.2500000000
K_POINTS { tpiba_b }
4
0.00000000 0.00000000 0.00000000 30.00000000
1.00000000 0.00000000 0.00000000 30.00000000
0.50000000 0.50000000 0.50000000 30.00000000
1.00000000 0.50000000 0.00000000 0.00000000
Finally a last example in which the lattice is specified through the ‘cell_parameters’ key
[23]:
inp = I.PwInput(file='IO_files/graphene_nscf.in')
inp
[23]:
{'control': {'verbosity': "'high'",
'calculation': "'nscf'",
'pseudo_dir': "'../pseudos'",
'prefix': "'ecut"},
'system': {'occupations': "'smearing'",
'smearing': "'fermi-dirac'",
'degauss': '0.0036749326',
'ibrav': '0',
'ntyp': '1',
'nat': '2',
'ecutwfc': '100',
'nbnd': '8'},
'electrons': {'conv_thr': '1e-08'},
'ions': {},
'cell': {},
'atomic_species': {'C': ['12.011', 'C_pbe-20082014.UPF']},
'atomic_positions': {'type': 'angstrom',
'values': [['C', [0.0, 0.0, 0.0]], ['C', [0.0, 1.42, 0.0]]]},
'kpoints': {'type': 'tpiba_b',
'values': [[0.0, 0.0, 0.0, 40.0],
[0.5, 0.28867513, 0.0, 40.0],
[0.66666667, 0.0, 0.0, 40.0],
[0.0, 0.0, 0.0, 0.0]]},
'cell_parameters': {'type': 'angstrom',
'values': [[2.4595121467, 0.0, 0.0],
[1.2297560734, 2.13, 0.0],
[0.0, 0.0, 10.0]]},
'file': 'IO_files/graphene_nscf.in'}
[24]:
print(inp.convert_string())
&control
calculation = 'nscf'
prefix = 'ecut
pseudo_dir = '../pseudos'
verbosity = 'high'
/&end
&system
degauss = 0.0036749326
ecutwfc = 100
ibrav = 0
nat = 2
nbnd = 8
ntyp = 1
occupations = 'smearing'
smearing = 'fermi-dirac'
/&end
&electrons
conv_thr = 1e-08
/&end
ATOMIC_SPECIES
C 12.011 C_pbe-20082014.UPF
ATOMIC_POSITIONS { angstrom }
C 0.0000000000 0.0000000000 0.0000000000
C 0.0000000000 1.4200000000 0.0000000000
K_POINTS { tpiba_b }
4
0.00000000 0.00000000 0.00000000 40.00000000
0.50000000 0.28867513 0.00000000 40.00000000
0.66666667 0.00000000 0.00000000 40.00000000
0.00000000 0.00000000 0.00000000 0.00000000
CELL_PARAMETERS angstrom
2.4595121467 0.0000000000 0.0000000000
1.2297560734 2.1300000000 0.0000000000
0.0000000000 0.0000000000 10.0000000000
[ ]: