# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function
import sys
import os
from aiida.plugins import DataFactory
from aiida.engine import submit
from aiida_quantumespresso.utils.pseudopotential import validate_and_prepare_pseudos_inputs
from aiida_quantumespresso.workflows.pw.base import PwBaseWorkChain
from ase import Atoms
import argparse
'''
The following part explains how to run the density functional theory (DFT) self-consistent simulations, using as example
the hexagonal boron nitride (hBN).
The starting point for a GW simulation is a self-consistent field (SCF) calculation of the electronic density,
and then a calculation of the electronic wavefunctions through a non-self-consistent (NSCF) DFT calculation.
So, the first AiiDA plugin used here is *aiida-quantumespresso*.
A step-by-step guide for input creation and management is provided in the jupyter-notebook version of the tutorials.
'''
[docs]def get_options():
parser = argparse.ArgumentParser(description='SCF calculation.')
parser.add_argument(
'--code',
type=str,
dest='code_id',
required=True,
help='The pw codename to use')
parser.add_argument(
'--pseudo',
type=str,
dest='pseudo_family',
required=True,
help='The pseudo family to use')
parser.add_argument(
'--time',
type=int,
dest='max_wallclock_seconds',
required=False,
default=30*60,
help='max wallclock in seconds')
parser.add_argument(
'--nodes',
type=int,
dest='num_machines',
required=False,
default=1,
help='number of machines')
parser.add_argument(
'--mpi',
type=int,
dest='num_mpiprocs_per_machine',
required=False,
default=1,
help='number of mpi processes per machine')
parser.add_argument(
'--threads',
type=int,
dest='num_cores_per_mpiproc',
required=False,
default=1,
help='number of threads per mpi process')
parser.add_argument(
'--queue_name',
type=str,
dest='queue_name',
required=False,
default=None,
help='queue(PBS) or partition(SLURM) name')
parser.add_argument(
'--qos',
type=str,
dest='qos',
required=False,
default=None,
help='qos name')
parser.add_argument(
'--account',
type=str,
dest='account',
required=False,
default=None,
help='account name')
args = parser.parse_args()
###### setting the machine options ######
options = {
'code_id': args.code_id,
'pseudo_family': args.pseudo_family,
'max_wallclock_seconds': args.max_wallclock_seconds,
'resources': {
"num_machines": args.num_machines,
"num_mpiprocs_per_machine": args.num_mpiprocs_per_machine,
"num_cores_per_mpiproc": args.num_cores_per_mpiproc,
},
'prepend_text': u"export OMP_NUM_THREADS="+str(args.num_cores_per_mpiproc),
}
if args.queue_name:
options['queue_name']=args.queue_name
if args.qos:
options['qos']=args.qos
if args.account:
options['account']=args.account
return options
[docs]def main(options):
###### setting the lattice structure of bulk hBN ######
alat = 2.4955987320 # Angstrom
the_cell = [[1.000000*alat, 0.000000, 0.000000],
[-0.500000*alat, 0.866025*alat, 0.000000],
[0.000000, 0.000000, 6.4436359260]]
atoms = Atoms('BNNB', [(1.2477994910, 0.7204172280, 0.0000000000),
(-0.0000001250, 1.4408346720, 0.0000000000),
(1.2477994910, 0.7204172280, 3.2218179630),
(-0.0000001250,1.4408346720, 3.2218179630)],
cell = [1,1,1])
atoms.set_cell(the_cell, scale_atoms=False)
atoms.set_pbc([True,True,True])
StructureData = DataFactory('structure')
structure = StructureData(ase=atoms)
###### setting the kpoints mesh ######
KpointsData = DataFactory('array.kpoints')
kpoints = KpointsData()
kpoints.set_kpoints_mesh([6,6,2])
###### setting the scf parameters ######
Dict = DataFactory('dict')
params_scf = {
'CONTROL': {
'calculation': 'scf',
'verbosity': 'high',
'wf_collect': True
},
'SYSTEM': {
'ecutwfc': 80.,
'force_symmorphic': True,
'nbnd': 20
},
'ELECTRONS': {
'mixing_mode': 'plain',
'mixing_beta': 0.7,
'conv_thr': 1.e-8,
'diago_thr_init': 5.0e-6,
'diago_full_acc': True
},
}
parameter_scf = Dict(dict=params_scf)
###### creation of the workchain ######
builder = PwBaseWorkChain.get_builder()
builder.pw.structure = structure
builder.pw.parameters = parameter_scf
builder.kpoints = kpoints
builder.pw.metadata.options.max_wallclock_seconds = \
options['max_wallclock_seconds']
builder.pw.metadata.options.resources = \
options['resources']
if 'queue_name' in options:
builder.pw.metadata.options.queue_name = options['queue_name']
if 'qos' in options:
builder.pw.metadata.options.qos = options['qos']
if 'account' in options:
builder.metadata.options.account = options['account']
if 'prepend_text' in options:
builder.pw.metadata.options.prepend_text = options['prepend_text']
builder.pw.code = load_code(options['code_id'])
family = load_group(options['pseudo_family'])
builder.pw.pseudos = family.get_pseudos(structure=structure)
return builder
if __name__ == "__main__":
[docs] options = get_options()
builder = main(options)
running = submit(builder)
print("Submitted PwBaseWorkchain; with pk=< {} >".format(running.pk))