Commits (2)
# Copyright 2015-2018 Lauri Himanen, Fawzi Mohamed, Ankit Kariryaa
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from phonopyparser.phonopy_calculators import PhonopyCalculatorInterface
from nomad.parsing.parser import FairdiParser
from .metainfo import m_env
class PhonopyParser(FairdiParser):
def __init__(self):
super().__init__(
name='parsers/phonopy', code_name='Phonopy', code_homepage='https://phonopy.github.io/phonopy/',
mainfile_name_re=(r'(.*/phonopy-FHI-aims-displacement-0*1/control.in$)|(.*/phonon.yaml)')
)
def parse(self, filepath, archive, logger=None):
self._metainfo_env = m_env
interface = PhonopyCalculatorInterface(filepath, archive, logger)
interface.parse()
from phonopyparser.phonopy_parser import PhonopyParser
import os
import numpy as np
import logging
import phonopy
from phonopy.units import THzToEv
......@@ -15,20 +16,34 @@ from nomad.datamodel.metainfo.public import section_run, section_system,\
section_k_band, section_k_band_segment, section_dos, section_frame_sequence,\
section_thermodynamical_properties, section_sampling_method, Workflow, Phonon, \
section_calculation_to_calculation_refs
from nomad.parsing.parser import FairdiParser
from .metainfo import m_env
class PhonopyCalculatorInterface:
def __init__(self, filepath, archive, logger=None):
self.filepath = os.path.abspath(filepath)
self.archive = archive
self.logger = logger
class PhonopyParser(FairdiParser):
def __init__(self, **kwargs):
super().__init__(
name='parsers/phonopy', code_name='Phonopy', code_homepage='https://phonopy.github.io/phonopy/',
mainfile_name_re=(r'(.*/phonopy-FHI-aims-displacement-0*1/control.in$)|(.*/phonon.yaml)')
)
self._kwargs = kwargs
@property
def mainfile(self):
return self._filepath
@mainfile.setter
def mainfile(self, val):
self._phonopy_obj = None
self.calculator = None
if 'control.in' in filepath:
self.calculator = 'fhi-aims'
elif 'phonon.yaml' in filepath:
self.calculator = 'vasp'
self.references = []
self._filepath = os.path.abspath(val)
@property
def calculator(self):
if 'control.in' in self.mainfile:
return 'fhi-aims'
elif 'phonon.yaml' in self.mainfile:
return 'vasp'
@property
def phonopy_obj(self):
......@@ -41,7 +56,7 @@ class PhonopyCalculatorInterface:
def _build_phonopy_object_vasp(self):
cwd = os.getcwd()
os.chdir(os.path.dirname(self.filepath))
os.chdir(os.path.dirname(self.mainfile))
phonopy_obj = phonopy.load('phonon.yaml')
os.chdir(cwd)
......@@ -50,8 +65,7 @@ class PhonopyCalculatorInterface:
def _build_phonopy_object_fhi_aims(self):
cwd = os.getcwd()
os.chdir(os.path.dirname(os.path.dirname(self.filepath)))
os.chdir(os.path.dirname(os.path.dirname(self.mainfile)))
cell_obj = read_aims("geometry.in")
control = Control()
if (len(control.phonon["supercell"]) == 3):
......@@ -63,7 +77,7 @@ class PhonopyCalculatorInterface:
set_of_forces, phonopy_obj, relative_paths = read_forces_aims(
cell_obj, supercell_matrix, displacement, sym)
prep_path = self.filepath.split("phonopy-FHI-aims-displacement-")
prep_path = self.mainfile.split("phonopy-FHI-aims-displacement-")
# Try to resolve references as paths relative to the upload root.
try:
......@@ -121,7 +135,7 @@ class PhonopyCalculatorInterface:
sec_dos.dos_values = dos
sec_dos.dos_energies = f
def parser_thermodynamical_properties(self):
def parse_thermodynamical_properties(self):
T, fe, _, cv = self.properties.get_thermodynamical_properties()
n_atoms = len(self.phonopy_obj.unitcell)
......@@ -165,9 +179,16 @@ class PhonopyCalculatorInterface:
sec_calc_refs.calculation_to_calculation_kind = 'source_calculation'
sec_calc_refs.calculation_to_calculation_external_url = ref
def parse(self):
def parse(self, filepath, archive, logger, **kwargs):
self.mainfile = filepath
self.archive = archive
self.logger = logger if logger is not None else logging
self._kwargs.update(kwargs)
self._metainfo_env = m_env
phonopy_obj = self.phonopy_obj
self.properties = PhononProperties(self.phonopy_obj, self.logger)
self.properties = PhononProperties(self.phonopy_obj, self.logger, **self._kwargs)
pbc = np.array((1, 1, 1), bool)
......@@ -227,7 +248,7 @@ class PhonopyCalculatorInterface:
self.parse_bandstructure()
self.parse_dos()
self.parser_thermodynamical_properties()
self.parse_thermodynamical_properties()
self.parse_ref()
sec_workflow = self.archive.m_create(Workflow)
......
import numpy as np
import logging
from ase.geometry import crystal_structure_from_cell
from ase.dft.kpoints import special_paths, parse_path_string
......@@ -55,15 +54,17 @@ def generate_kpath_ase(cell, symprec):
class PhononProperties():
def __init__(self, phonopy_obj, logger=None):
if logger is None:
logger = logging
def __init__(self, phonopy_obj, logger, **kwargs):
self.logger = logger
self.phonopy_obj = phonopy_obj
self.t_max = kwargs.get('t_max', 1000)
self.t_min = kwargs.get('t_min', 0)
self.t_step = kwargs.get('t_step', 10)
self.n_atoms = len(phonopy_obj.unitcell)
mesh_density = (2 * 80 ** 3) / self.n_atoms
k_mesh = kwargs.get('k_mesh', 60)
mesh_density = (2 * k_mesh ** 3) / self.n_atoms
mesh_number = np.round(mesh_density**(1. / 3.))
self.mesh = [mesh_number, mesh_number, mesh_number]
......@@ -139,13 +140,9 @@ class PhononProperties():
def get_thermodynamical_properties(self):
phonopy_obj = self.phonopy_obj
t_max = 100
t_min = 0
t_step = 10
mesh = self.mesh
phonopy_obj.set_mesh(mesh, is_gamma_center=True)
phonopy_obj.set_thermal_properties(t_step=t_step, t_max=t_max, t_min=t_min)
phonopy_obj.set_mesh(self.mesh, is_gamma_center=True)
phonopy_obj.set_thermal_properties(
t_step=self.t_step, t_max=self.t_max, t_min=self.t_min)
T, fe, entropy, cv = phonopy_obj.get_thermal_properties()
kJmolToEv = 1.0 / EvTokJmol
fe = fe * kJmolToEv
......