Skip to content

Commit

Permalink
Merge branch 'track-data-prov' into develop
Browse files Browse the repository at this point in the history
  • Loading branch information
atztogo committed Jan 24, 2021
2 parents 13efc54 + e3c2505 commit d256974
Show file tree
Hide file tree
Showing 3 changed files with 116 additions and 60 deletions.
138 changes: 92 additions & 46 deletions aiida_phonopy/common/builders.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,69 @@
from aiida.engine import calcfunction
from aiida.plugins import DataFactory, WorkflowFactory, CalculationFactory
from aiida.common import InputValidationError
from aiida.orm import Str, Bool, Code

KpointsData = DataFactory("array.kpoints")
Dict = DataFactory('dict')
StructureData = DataFactory('structure')
PotcarData = DataFactory('vasp.potcar')

@calcfunction
def get_force_calcjob_inputs(calculator_settings, supercell):
return _get_calcjob_inputs(calculator_settings, supercell, 'forces')

def get_calcjob_builder(structure, calculator_settings, calc_type=None,
pressure=0.0, label=None):
if calc_type:
code = Code.get_from_string(
calculator_settings[calc_type]['code_string'])
else:
code = Code.get_from_string(
calculator_settings['code_string'])

@calcfunction
def get_nac_calcjob_inputs(calculator_settings, unitcell):
return _get_calcjob_inputs(calculator_settings, unitcell, 'nac')


def _get_calcjob_inputs(calculator_settings, supercell, calc_type):
code = Code.get_from_string(calculator_settings[calc_type]['code_string'])
if code.attributes['input_plugin'] in ['vasp.vasp']:
if calc_type is None:
settings_dict = calculator_settings.get_dict()
else:
settings_dict = calculator_settings[calc_type]
settings = calculator_settings[calc_type]
builder_inputs = {'options': _get_vasp_options(settings),
'parameters': _get_vasp_parameters(settings),
'settings': _get_vasp_settings(settings),
'kpoints': _get_vasp_kpoints(settings, supercell)}
else:
raise RuntimeError("Code could not be found.")

potential_family = Str(settings['potential_family'])
potential_mapping = Dict(dict=settings['potential_mapping'])
builder_inputs.update({'potential_family': potential_family,
'potential_mapping': potential_mapping})
return builder_inputs

return _get_vasp_builder(structure,
settings_dict,
pressure=pressure,
label=label)

def get_calcjob_builder(structure, code_string, builder_inputs, label=None):
code = Code.get_from_string(code_string)
if code.attributes['input_plugin'] in ['vasp.vasp']:
VaspWorkflow = WorkflowFactory('vasp.vasp')
builder = VaspWorkflow.get_builder()
# VaspCalc = CalculationFactory('vasp.vasp')
# potential = PotcarData.get_potcars_from_structure(
# structure, builder_inputs['potential_family'].value,
# mapping=builder_inputs['potential_mapping'].get_dict())
# builder = VaspCalc.get_builder()
if label:
builder.metadata.label = label
builder.code = Code.get_from_string(code_string)
builder.structure = structure
builder.settings = builder_inputs['settings']
builder.parameters = builder_inputs['parameters']
builder.kpoints = builder_inputs['kpoints']
builder.potential_family = builder_inputs['potential_family']
builder.potential_mapping = builder_inputs['potential_mapping']
builder.options = builder_inputs['options']
builder.clean_workdir = Bool(False)
# builder.potential = potential
# builder.metadata['options'].update(builder_inputs['options'].get_dict())
else:
raise RuntimeError("Code could not be found.")

return builder


def get_immigrant_builder(calculation_folder,
calculator_settings,
Expand Down Expand Up @@ -62,46 +97,30 @@ def get_immigrant_builder(calculation_folder,
return builder


def _get_vasp_builder(structure, settings_dict, pressure=0.0, label=None):
"""
Generate the input paramemeters needed to run a calculation for VASP
def _get_vasp_options(settings_dict):
return Dict(dict=settings_dict['options'])

:param structure: StructureData object containing the crystal structure
:param settings: dict object containing a dictionary with the
INCAR parameters
:return: Calculation process object, input dictionary
"""

code_string = settings_dict['code_string']
VaspWorkflow = WorkflowFactory('vasp.vasp')
builder = VaspWorkflow.get_builder()
if label:
builder.metadata.label = label
builder.code = Code.get_from_string(code_string)
builder.structure = structure
options = Dict(dict=settings_dict['options'])
builder.options = options
builder.clean_workdir = Bool(False)
def _get_vasp_parameters(settings_dict):
parameters = settings_dict['parameters']
incar = parameters['incar']
keys_lower = [key.lower() for key in incar]
if 'ediff' not in keys_lower:
incar.update({'EDIFF': 1.0E-8})
return Dict(dict=parameters)


def _get_vasp_settings(settings_dict):
if 'parser_settings' in settings_dict:
parser_settings_dict = settings_dict['parser_settings']
else:
parser_settings_dict = {}
if 'add_forces' not in parser_settings_dict:
parser_settings_dict.update({'add_forces': True})
return Dict(dict={'parser_settings': parser_settings_dict})

builder.settings = DataFactory('dict')(
dict={'parser_settings': parser_settings_dict})

incar = dict(settings_dict['parameters'])
keys_lower = [key.lower() for key in incar]
if 'ediff' not in keys_lower:
incar.update({'EDIFF': 1.0E-8})
builder.parameters = Dict(dict=incar)
builder.potential_family = Str(settings_dict['potential_family'])
builder.potential_mapping = Dict(
dict=settings_dict['potential_mapping'])

def _get_vasp_kpoints(settings_dict, structure):
kpoints = KpointsData()
kpoints.set_cell_from_structure(structure)
if 'kpoints_density' in settings_dict:
Expand All @@ -119,6 +138,33 @@ def _get_vasp_builder(structure, settings_dict, pressure=0.0, label=None):
'no kpoint definition in input. '
'Define either kpoints_density or kpoints_mesh')

builder.kpoints = kpoints
return kpoints


def _get_vasp_builder(structure, settings_dict, label=None):
"""
Generate the input paramemeters needed to run a calculation for VASP
:param structure: StructureData object containing the crystal structure
:param settings: dict object containing a dictionary with the
INCAR parameters
:return: Calculation process object, input dictionary
"""

code_string = settings_dict['code_string']
VaspWorkflow = WorkflowFactory('vasp.vasp')
builder = VaspWorkflow.get_builder()
if label:
builder.metadata.label = label
builder.code = Code.get_from_string(code_string)
builder.structure = structure
builder.options = _get_vasp_options(settings_dict)
builder.clean_workdir = Bool(False)
builder.settings = _get_vasp_settings(settings_dict)
builder.parameters = _get_vasp_parameters(settings_dict)
builder.potential_family = Str(settings_dict['potential_family'])
builder.potential_mapping = Dict(
dict=settings_dict['potential_mapping'])
builder.kpoints = _get_vasp_kpoints(settings_dict, structure)

return builder
13 changes: 8 additions & 5 deletions aiida_phonopy/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -88,11 +88,14 @@ def get_vasp_force_sets_dict(**forces_dict):
else:
forces[num - 1] = forces_ndarray
elif 'misc' in key:
energy = forces_dict[key]['total_energies']['energy_no_entropy']
if num == 0:
energy_0 = energy
else:
energies[num - 1] = energy
for energy_key in ('energy_extrapolated', ):
if energy_key in forces_dict[key]['total_energies']:
energy = forces_dict[key]['total_energies'][energy_key]
if num == 0:
energy_0 = energy
else:
energies[num - 1] = energy
break

if forces_0 is not None:
for forces_ndarray in forces:
Expand Down
25 changes: 16 additions & 9 deletions aiida_phonopy/workflows/phonopy.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@
from aiida.orm import Float, Bool, Str, Code
from aiida.engine import if_, while_
from aiida_phonopy.common.builders import (
get_calcjob_builder, get_immigrant_builder)
get_calcjob_builder, get_force_calcjob_inputs,
get_nac_calcjob_inputs, get_immigrant_builder)
from aiida_phonopy.common.utils import (
get_force_constants, get_nac_params, get_phonon,
generate_phonopy_cells, compare_structures,
Expand Down Expand Up @@ -221,11 +222,14 @@ def run_force_and_nac_calculations(self):
def _run_force_calculations(self):
# Forces
self.report('run force calculations')
builder_inputs = get_force_calcjob_inputs(
self.inputs.calculator_settings, self.ctx.supercell)
for key in self.ctx.supercells:
builder = get_calcjob_builder(self.ctx.supercells[key],
self.inputs.calculator_settings,
calc_type='forces',
label=key)
builder = get_calcjob_builder(
self.ctx.supercells[key],
self.inputs.calculator_settings['forces']['code_string'],
builder_inputs,
label=key)
future = self.submit(builder)
label = "force_calc_%s" % key.split('_')[-1]
self.report('{} pk = {}'.format(label, future.pk))
Expand All @@ -236,10 +240,13 @@ def _run_nac_calculation(self):
self.report('run nac calculation')
if self.is_nac():
self.report('calculate born charges and dielectric constant')
builder = get_calcjob_builder(self.ctx.primitive,
self.inputs.calculator_settings,
calc_type='nac',
label='born_and_epsilon')
builder_inputs = get_nac_calcjob_inputs(
self.inputs.calculator_settings, self.ctx.primitive)
builder = get_calcjob_builder(
self.ctx.primitive,
self.inputs.calculator_settings['nac']['code_string'],
builder_inputs,
label='born_and_epsilon')
future = self.submit(builder)
self.report('born_and_epsilon: {}'.format(future.pk))
self.to_context(**{'born_and_epsilon_calc': future})
Expand Down

0 comments on commit d256974

Please sign in to comment.