Skip to content

Commit

Permalink
Immigrant methods were moved to Forces and NacParams workchains
Browse files Browse the repository at this point in the history
  • Loading branch information
atztogo committed Jun 4, 2021
1 parent 5f83f47 commit e747c4e
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 77 deletions.
15 changes: 9 additions & 6 deletions aiida_phonopy/common/builders.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,24 +116,27 @@ def get_vasp_immigrant_inputs(folder_path, calculator_settings, label=None):
"""
code = Code.get_from_string(calculator_settings['code_string'])

if code.get_input_plugin_name() == 'vasp.immigrant':
if code.get_input_plugin_name() == 'vasp.vasp':
inputs = {}
inputs['code'] = code
inputs['folder_path'] = Str(folder_path)
if 'parser_settings' in calculator_settings:
inputs['settings'] = Dict(
dict={'parser_settings': calculator_settings['parser_settings']})
if 'options' in calculator_settings:
inputs['options'] = Dict(dict={calculator_settings['options']})
inputs['options'] = Dict(dict=calculator_settings['options'])
if 'metadata' in calculator_settings:
inputs['metadata'] = calculator_settings['metadata']
if label:
inputs['metadata']['label'] = label
else:
inputs['metadata'] = {'metadata': {'label': label}}
elif label:
inputs['metadata'] = {'label': label}
if 'potential_family' in calculator_settings:
inputs['potential_family'] = Str(
calculator_settings['potential_family'])
if 'potential_mapping' in calculator_settings:
inputs['potential_mapping'] = Str(
calculator_settings['potential_mapping'])
inputs['potential_mapping'] = Dict(
dict=calculator_settings['potential_mapping'])
else:
raise RuntimeError("Code could not be found.")

Expand Down
9 changes: 9 additions & 0 deletions aiida_phonopy/common/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -302,6 +302,15 @@ def compare_structures(cell_ref, cell_calc, symmetry_tolerance):
return succeeded


def get_structure_from_vasp_immigrant(calc_node):
"""Get structure from VASP immigrant workchain."""
for lt in calc_node.get_outgoing():
if 'iteration_' in lt.link_label:
structure = lt.node.inputs.structure
return structure
return None


def get_mesh_property_data(ph, mesh):
"""Return total DOS, PDOS, thermal properties."""
ph.set_mesh(mesh)
Expand Down
53 changes: 46 additions & 7 deletions aiida_phonopy/workflows/forces.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
"""Workflow to calculate supercell forces."""

import numpy as np
from aiida.engine import WorkChain, calcfunction
from aiida.plugins import DataFactory
from aiida.engine import WorkChain, calcfunction, if_
from aiida.plugins import DataFactory, WorkflowFactory
from aiida.orm import Code
from aiida_phonopy.common.builders import (
get_calcjob_inputs, get_calculator_process)

get_calcjob_inputs, get_calculator_process, get_vasp_immigrant_inputs)
from aiida_phonopy.common.utils import (
compare_structures, get_structure_from_vasp_immigrant)

Float = DataFactory('float')
Dict = DataFactory('dict')
Str = DataFactory('str')
ArrayData = DataFactory('array')
StructureData = DataFactory('structure')

Expand Down Expand Up @@ -97,10 +99,18 @@ def define(cls, spec):
super().define(spec)
spec.input('structure', valid_type=StructureData, required=True)
spec.input('calculator_settings', valid_type=Dict, required=True)

spec.input('symmetry_tolerance', valid_type=Float,
default=lambda: Float(1e-5))
spec.input('immigrant_calculation_folder', valid_type=Str,
required=False)
spec.outline(
cls.run_calculation,
cls.finalize
if_(cls.import_calculation_from_files)(
cls.read_calculation_from_folder,
cls.validate_imported_structure,
).else_(
cls.run_calculation,
),
cls.finalize,
)

spec.output('forces', valid_type=ArrayData, required=True)
Expand All @@ -112,6 +122,13 @@ def define(cls, spec):
spec.exit_code(
1002, 'ERROR_NO_ENERGY',
message='energy could not be retrieved from calculaton.')
spec.exit_code(
1003, 'ERROR_STRUCTURE_VALIDATION',
message='input and imported structures are different.')

def import_calculation_from_files(self):
"""Return boolen for outline."""
return 'immigrant_calculation_folder' in self.inputs

def run_calculation(self):
"""Run supercell force calculation."""
Expand All @@ -125,6 +142,28 @@ def run_calculation(self):
self.report('{} pk = {}'.format(self.metadata.label, future.pk))
self.to_context(**{'calc': future})

def read_calculation_from_folder(self):
"""Import supercell force calculation using immigrant."""
self.report('import supercell force calculation data in files.')
force_folder = self.inputs.immigrant_calculation_folder
inputs = get_vasp_immigrant_inputs(
force_folder.value, self.inputs.calculator_settings.dict,
label=self.metadata.label)
VaspImmigrant = WorkflowFactory('vasp.immigrant')
future = self.submit(VaspImmigrant, **inputs)
self.report('{} pk = {}'.format(self.metadata.label, future.pk))
self.to_context(**{'calc': future})

def validate_imported_structure(self):
"""Validate imported supercell structure."""
self.report('validate imported supercell structures')
supercell_ref = self.inputs.structure
supercell_calc = get_structure_from_vasp_immigrant(self.ctx.calc)
if not compare_structures(supercell_ref,
supercell_calc,
self.inputs.symmetry_tolerance):
return self.exit_codes.ERROR_STRUCTURE_VALIDATION

def finalize(self):
"""Finalize force calculation."""
outputs = self.ctx.calc.outputs
Expand Down
47 changes: 41 additions & 6 deletions aiida_phonopy/workflows/nac_params.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,16 @@
"""Workflow to calculate NAC params."""

from aiida.engine import WorkChain, calcfunction, while_, append_
from aiida.plugins import DataFactory
from aiida.engine import WorkChain, calcfunction, while_, append_, if_
from aiida.plugins import DataFactory, WorkflowFactory
from aiida_phonopy.common.builders import (
get_calcjob_inputs, get_calculator_process, get_plugin_names)
from aiida_phonopy.common.utils import phonopy_atoms_from_structure
get_calcjob_inputs, get_calculator_process, get_plugin_names,
get_vasp_immigrant_inputs)
from aiida_phonopy.common.utils import (
phonopy_atoms_from_structure, get_structure_from_vasp_immigrant)
from phonopy.structure.symmetry import symmetrize_borns_and_epsilon

Float = DataFactory('float')
Str = DataFactory('str')
Dict = DataFactory('dict')
ArrayData = DataFactory('array')
StructureData = DataFactory('structure')
Expand All @@ -23,12 +26,20 @@ def _get_nac_params(ctx, symmetry_tolerance):
needs information of the structure where those values were calcualted and
the target primitive cell structure.
When using immigrant, structure is in the immigrant calculation but not
the workchain. 'structure' should be accessible in the vasp immigrant
workchain level, and this should be fixed in aiida-vasp.
"""
if ctx.plugin_names[0] == 'vasp.vasp':
calc = ctx.nac_params_calcs[0]
if 'structure' in calc.inputs:
structure = calc.inputs.structure
else:
structure = get_structure_from_vasp_immigrant(calc)
nac_params = get_vasp_nac_params(calc.outputs.born_charges,
calc.outputs.dielectrics,
calc.inputs.structure,
structure,
symmetry_tolerance)
elif ctx.plugin_names[0] == 'quantumespresso.pw':
pw_calc = ctx.nac_params_calcs[0]
Expand Down Expand Up @@ -105,11 +116,17 @@ def define(cls, spec):
spec.input('calculator_settings', valid_type=Dict, required=True)
spec.input('symmetry_tolerance', valid_type=Float,
default=lambda: Float(1e-5))
spec.input('immigrant_calculation_folder', valid_type=Str,
required=False)

spec.outline(
cls.initialize,
while_(cls.continue_calculation)(
cls.run_calculation,
if_(cls.import_calculation_from_files)(
cls.read_calculation_from_folder,
).else_(
cls.run_calculation,
),
),
cls.finalize,
)
Expand All @@ -127,6 +144,10 @@ def continue_calculation(self):
self.ctx.iteration += 1
return True

def import_calculation_from_files(self):
"""Return boolen for outline."""
return 'immigrant_calculation_folder' in self.inputs

def initialize(self):
"""Initialize outline control parameters."""
self.report('initialization')
Expand Down Expand Up @@ -156,6 +177,20 @@ def run_calculation(self):
self.report('nac_params: {}'.format(future.pk))
self.to_context(nac_params_calcs=append_(future))

def read_calculation_from_folder(self):
"""Import supercell force calculation using immigrant."""
self.report('import calculation data in files %d/%d'
% (self.ctx.iteration, self.ctx.max_iteration))
label = "nac_params_%d" % self.ctx.iteration
force_folder = self.inputs.immigrant_calculation_folder
inputs = get_vasp_immigrant_inputs(
force_folder.value, self.inputs.calculator_settings.dict,
label=label)
VaspImmigrant = WorkflowFactory('vasp.immigrant')
future = self.submit(VaspImmigrant, **inputs)
self.report('nac_params: {}'.format(future.pk))
self.to_context(nac_params_calcs=append_(future))

def finalize(self):
"""Finalize NAC params calculation."""
self.report('finalization')
Expand Down

0 comments on commit e747c4e

Please sign in to comment.