Skip to content

Instantly share code, notes, and snippets.

@unkcpz
Last active April 6, 2016 08:42
Show Gist options
  • Save unkcpz/97598a76b312f52122752b41602575c3 to your computer and use it in GitHub Desktop.
Save unkcpz/97598a76b312f52122752b41602575c3 to your computer and use it in GitHub Desktop.
aiida's workflow for ecutwfc test of pseudopotential.
# -*- coding: utf-8 -*-
from __future__ import division
import aiida.common
from aiida.common import aiidalogger
from aiida.orm.workflow import Workflow
from aiida.orm import Code, Computer
from aiida.orm import CalculationFactory, DataFactory
__copyright__ = u"Copyright (c), 2015, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (Theory and Simulation of Materials (THEOS) and National Centre for Computational Design and Discovery of Novel Materials (NCCR MARVEL)), Switzerland and ROBERT BOSCH LLC, USA. All rights reserved."
__license__ = "MIT license, see LICENSE.txt file"
__version__ = "0.5.0"
__contributors__ = "Andrea Cepellotti, Giovanni Pizzi, Martin Uhrin"
# example: pseudopotential cutoff test
UpfData = DataFactory('upf')
ParameterData = DataFactory('parameter')
KpointsData = DataFactory('array.kpoints')
StructureData = DataFactory('structure')
logger = aiidalogger.getChild('WorkflowPPcutoff')
## WorkflowPPcutoff
class Workflow_EOC(Workflow):
def __init__(self, **kwargs):
super(Workflow_EOC,self).__init__(**kwargs)
## Parameters generators
def get_structure(self, x_material='Ba'):
alat = 20 # angstrom
cell = [[alat, 0., 0.,],
[0., alat, 0.,],
[0., 0., alat,],
]
s = StructureData(cell=cell)
s.append_atom(position=(0, 0, 0), symbols=x_material)
# s.store()
return s
def get_pw_parameters(self, ecutwfc=30, ecutrho=120):
parameters = ParameterData(dict={
'CONTROL':{
'calculation': 'scf',
'restart_mode': 'from_scratch',
'wf_collect': True,
},
'SYSTEM':{
'ecutwfc': ecutwfc,
'ecutrho': ecutrho,
'occupations':'smearing',
'smearing':'gauss',
'degauss':0.02,
},
'ELECTRONS':{
'conv_thr':1.e-6,
}
})
return parameters
def get_kpoints(self):
kpoints = KpointsData()
kpoints.set_kpoints_mesh([1,1,1]) # Need attach setting gamma_only in calc.use_setting
# kpoints.store()
return kpoints
## Calculations generators
def get_pw_calculation(self, pw_structure, pw_parameters, pw_kpoint):
params = self.get_parameters()
pw_codename = params['pw_codename']
para_env = params['para_env']
num_procs = params['num_procs']
max_wallclock_seconds = params['max_wallclock_seconds']
pseudo_family = params['pseudo_family']
code = Code.get_from_string(pw_codename)
computer = code.get_remote_computer()
QECalc = CalculationFactory('quantumespresso.pw')
calc = QECalc(computer=computer)
calc.set_max_wallclock_seconds(max_wallclock_seconds)
calc.set_resources({"parallel_env": para_env, "tot_num_mpiprocs": num_procs})
# calc.store()
calc.use_code(code)
calc.use_structure(pw_structure)
calc.use_pseudos_from_family(pseudo_family)
calc.use_parameters(pw_parameters)
# needed for kpoints mesh (1, 1, 1) kpoints.
settings = ParameterData(dict={'gamma_only':True})
calc.use_settings(settings)
calc.use_kpoints(pw_kpoint)
calc.store_all()
return calc
## Workflow steps
@Workflow.step
def start(self):
params = self.get_parameters()
x_material = params['x_material']
self.append_to_report(x_material + " pseudopotential cutoff energy calculating...")
self.next(self.eoc)
@Workflow.step
def eoc(self):
from aiida.orm import Code, Computer, CalculationFactory
params = self.get_parameters()
x_material = params['x_material']
uspp = False
# uspp as example, modified after
if uspp:
self.append_to_report("pseudopotential is USPPs type.")
cutrange = range(10,101,10)
else:
self.append_to_report("pseudopotential is not USPPs type.")
cutrange = range(30,101,10)
aiidalogger.info("storing cutrange as " + str(cutrange))
self.add_attribute('cutrange', cutrange)
for a in cutrange:
self.append_to_report("Preparing cutoff energy of {0} with ecutwfc: {1}".format(x_material, a))
# If there are ultrasoft PP, a larger value than the default is
# often desirable (ecutrho = 8 to 12 times ecutwfc, typically).
t = 8*a if uspp else 4*a
calc = self.get_pw_calculation(self.get_structure(x_material=x_material),
self.get_pw_parameters(a, t),
self.get_kpoints()
)
self.attach_calculation(calc)
self.next(self.conv)
@Workflow.step
def conv(self):
import numpy as np
params = self.get_parameters()
x_material = params['x_material']
# x_material = self.get_parameters("x_material")
cutrange = self.get_attribute("cutrange")
aiidalogger.info("Retrieving cutrange as {0}".format(cutrange))
eoc_calcs = self.get_step_calculations(self.eoc)
# Calculate results
e_calcs = [c.res.energy for c in eoc_calcs]
e_calcs = zip(*sorted(zip(cutrange, e_calcs)))[1]
t_diff = [t - s for s, t in zip(e_calcs, e_calcs[1:])]
# t_diff = np.diff(e_calcs)
for i in range(len(cutrange)):
self.append_to_report(x_material + " simulated with ecutwfc=" + str(cutrange[i])+ ", e=" + str(e_calcs[i]))
# Find cutoff energy with conv standard
to_ind = next(i for i in t_diff if i <= 1.e-5)
ind = t_diff.index(to_ind)
self.append_to_report(x_material + " Recommented converge ecutwfc is:" + str(cutrange[ind]))
self.next(self.exit)
#!/usr/bin/env runaiida
# -*- coding: utf-8 -*-
from aiida.workflows.user.wf_ppcutoff import Workflow_EOC
import sys
from aiida.common.example_helpers import test_and_get_code
__copyright__ = u"Copyright (c), 2015, ECOLE POLYTECHNIQUE FEDERALE DE LAUSANNE (Theory and Simulation of Materials (THEOS) and National Centre for Computational Design and Discovery of Novel Materials (NCCR MARVEL)), Switzerland and ROBERT BOSCH LLC, USA. All rights reserved."
__license__ = "MIT license, see LICENSE.txt file"
__version__ = "0.5.0"
__contributors__ = "Andrea Cepellotti, Giovanni Pizzi, Martin Uhrin"
# example: runs a set of calculation for at various cutoff energy
# user$ ./wf_ppcutoff.py Ba lda_hgh
UpfData = DataFactory('upf')
codename = "pw53@rocks"
code = test_and_get_code(codename, expected_code_type='quantumespresso.pw')
element = sys.argv[1]
try:
pseudo_family = sys.argv[2]
except IndexError:
print >> sys.stderr, "Error, you must pass as second parameter the pseudofamily"
print >> sys.stderr, "Valid UPF families are:"
# print >> sys.stderr, "\n".join("* {}".format(i.name) for i in valid_pseudo_groups)
sys.exit(1)
try:
UpfData.get_upf_group(pseudo_family)
except NotExistent:
print >> sys.stderr, "You set pseudo_family='{}',".format(pseudo_family)
print >> sys.stderr, "but no group with such a name found in the DB."
print >> sys.stderr, "Valid UPF groups are:"
# print >> sys.stderr, ",".join(i.name for i in valid_pseudo_groups)
sys.exit(1)
ParameterData = DataFactory('parameter')
params_dict = { 'pw_codename': codename,
'para_env': 'orte',
'num_procs': 4,
'max_wallclock_seconds': 60*10,
'pseudo_family': pseudo_family,
'x_material': element,
}
w = Workflow_EOC()
w.set_params(params_dict)
w.start()
@unkcpz
Copy link
Author

unkcpz commented Apr 6, 2016

uspp control. 8* for uspp.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment