Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implemented support for elasticity calculion in matdyn #795

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 10 additions & 4 deletions aiida_quantumespresso/calculations/matdyn.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
# -*- coding: utf-8 -*-
"""`CalcJob` implementation for the matdyn.x code of Quantum ESPRESSO."""
from aiida import orm

from aiida_quantumespresso.calculations.namelists import NamelistsCalculation
from aiida_quantumespresso.data.force_constants import ForceConstantsData

Expand All @@ -12,16 +11,18 @@ class MatdynCalculation(NamelistsCalculation):
_PHONON_FREQUENCIES_NAME = 'phonon_frequencies.dat'
_PHONON_MODES_NAME = 'phonon_displacements.dat'
_PHONON_DOS_NAME = 'phonon_dos.dat'
_PHONON_ELASTICITY_NAME = 'phonon_elasticity.yaml'

_default_namelists = ['INPUT']
_blocked_keywords = [
('INPUT', 'flfrq', _PHONON_FREQUENCIES_NAME), # output frequencies
('INPUT', 'flvec', _PHONON_MODES_NAME), # output displacements
('INPUT', 'fldos', _PHONON_DOS_NAME), # output density of states
('INPUT', 'flelc', _PHONON_ELASTICITY_NAME), # output elastic properties
('INPUT', 'q_in_cryst_coord', True), # kpoints always in crystal coordinates
]

_internal_retrieve_list = [_PHONON_FREQUENCIES_NAME, _PHONON_DOS_NAME]
_internal_retrieve_list = [_PHONON_FREQUENCIES_NAME, _PHONON_DOS_NAME, _PHONON_ELASTICITY_NAME]
_default_parser = 'quantumespresso.matdyn'

@classmethod
Expand All @@ -34,13 +35,16 @@ def define(cls, spec):
spec.inputs.pop('parent_folder')
spec.output('output_parameters', valid_type=orm.Dict)
spec.output('output_phonon_bands', valid_type=orm.BandsData)
spec.output('output_elasticity', valid_type=orm.Dict)
spec.default_output_node = 'output_parameters'
spec.exit_code(310, 'ERROR_OUTPUT_STDOUT_READ',
message='The stdout output file could not be read.')
spec.exit_code(312, 'ERROR_OUTPUT_STDOUT_INCOMPLETE',
message='The stdout output file was incomplete probably because the calculation got interrupted.')
spec.exit_code(330, 'ERROR_OUTPUT_FREQUENCIES',
message='The output frequencies file could not be read from the retrieved folder.')
spec.exit_code(340, 'ERROR_OUTPUT_ELASTICITY',
message='The output elasticity file could not be read from the retrieved folder.')
spec.exit_code(410, 'ERROR_OUTPUT_KPOINTS_MISSING',
message='Number of kpoints not found in the output data')
spec.exit_code(411, 'ERROR_OUTPUT_KPOINTS_INCOMMENSURATE',
Expand All @@ -56,7 +60,7 @@ def _get_following_text(self):

kpoints_string = [f'{len(kpoints)}']
for kpoint in kpoints:
kpoints_string.append('{:18.10f} {:18.10f} {:18.10f}'.format(*kpoint)) # pylint: disable=consider-using-f-string
kpoints_string.append('{:18.10f} {:18.10f} {:18.10f}'.format(*kpoint))

return '\n'.join(kpoints_string) + '\n'

Expand All @@ -71,7 +75,9 @@ def prepare_for_submission(self, folder):
:return: :py:`~aiida.common.datastructures.CalcInfo` instance.
"""
force_constants = self.inputs.force_constants
self._blocked_keywords.append(('INPUT', 'flfrc', force_constants.filename))
flfrc_tuple = ('INPUT', 'flfrc', force_constants.filename)
if flfrc_tuple not in self._blocked_keywords:
self._blocked_keywords.append(flfrc_tuple)

calcinfo = super().prepare_for_submission(folder)
calcinfo.local_copy_list.append((force_constants.uuid, force_constants.filename, force_constants.filename))
Expand Down
29 changes: 25 additions & 4 deletions aiida_quantumespresso/parsers/matdyn.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
from qe_tools import CONSTANTS

from aiida_quantumespresso.calculations.matdyn import MatdynCalculation

from .base import Parser


Expand All @@ -15,6 +14,7 @@ def parse(self, **kwargs):
retrieved = self.retrieved
filename_stdout = self.node.get_option('output_filename')
filename_frequencies = MatdynCalculation._PHONON_FREQUENCIES_NAME
filename_elasticity = MatdynCalculation._PHONON_ELASTICITY_NAME

if filename_stdout not in retrieved.list_object_names():
return self.exit(self.exit_codes.ERROR_OUTPUT_STDOUT_READ)
Expand Down Expand Up @@ -48,6 +48,12 @@ def parse(self, **kwargs):
output_bands.set_kpointsdata(kpoints_for_bands)
output_bands.set_bands(parsed_data.pop('phonon_bands'), units='THz')

if filename_elasticity in retrieved.list_object_names():
output_elasticity = parse_elasticity_file(retrieved.get_object_content(filename_elasticity))
self.out('output_elasticity', orm.Dict(dict=output_elasticity))
else:
return self.exit(self.exit_codes.ERROR_OUTPUT_ELASTICITY)

for message in parsed_data['warnings']:
self.logger.error(message)

Expand All @@ -67,9 +73,8 @@ def parse_raw_matdyn_phonon_file(phonon_frequencies):
* num_kpoints: number of kpoints read from the file
* phonon_bands: BandsData object with the bands for each kpoint
"""
import re

import numpy
import re

parsed_data = {}
parsed_data['warnings'] = []
Expand Down Expand Up @@ -99,7 +104,7 @@ def parse_raw_matdyn_phonon_file(phonon_frequencies):
# case in which there are two frequencies attached like -1204.1234-1020.536
if '-' in b:
c = re.split('(-)', b)
d = [i for i in c if i != '']
d = [i for i in c if i is not '']
for i in range(0, len(d), 2): # d should have an even number of elements
corrected_data.append(float(d[i] + d[i + 1]))
else:
Expand All @@ -123,3 +128,19 @@ def parse_raw_matdyn_phonon_file(phonon_frequencies):
parsed_data['phonon_bands'] = freq_matrix

return parsed_data


def parse_elasticity_file(elasticity_file):
"""Parses the elastic properties file.

:param elasticity_file: elasticity file from the matdyn calculation

:return dict parsed_data:
A dictionary of elastic properties, see example output yaml file
of elasticity about the supported keys.
"""
import yaml

parsed_data = yaml.full_load(elasticity_file)

return parsed_data