Commit a2f03d73 authored by Daniel Speckhard's avatar Daniel Speckhard
Browse files

nomad-faird integration.

parent 6236d903
......@@ -9,6 +9,7 @@ syntax: glob
*.pyc
*.bk
*.swp
*.egg-info
.DS_Store
# logging files
......
# Copyright 2016-2018 Fawzi Mohamed, Danio Brambila
#
#
# 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.
......@@ -13,7 +13,7 @@
# limitations under the License.
# coding=utf-8
#### phonopy parser written by Hagen-Henrik Kowalski and based on the original work of Joerg Mayer on phonopy-FHI-aims
#### phonopy parser written by Hagen-Henrik Kowalski and based on the original work of Joerg Mayer on phonopy-FHI-aims
import numpy as np
import past
......@@ -74,17 +74,17 @@ def Write_FORCE_CONSTANTS(phonopy_obj, set_of_forces):
Hessian = get_force_constants(forces, phonopy_obj.symmetry, phonopy_obj.supercell)
####
#### generate_kPath prepares the path genereated by ASE to be used with
#### generate_kPath prepares the path genereated by ASE to be used with
#### the function post_process_band
def generate_kPath_ase(cell, symprec):
eig_val_max = np.real(np.linalg.eigvals(cell)).max()
eps = eig_val_max*symprec
lattice = crystal_structure_from_cell(cell, eps)
lattice = crystal_structure_from_cell(cell, eps)
paths = parse_path_string(special_paths[lattice])
points = special_points[lattice]
k_points = []
k_points = []
for p in paths:
k_points.append([points[k] for k in p])
for index in range(len(p)):
......@@ -117,9 +117,9 @@ def generate_kPath_ase(cell, symprec):
def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, tol = 1e-6):
symmetry = Symmetry(cell_obj)
phonopy_obj = Phonopy(cell_obj,
supercell_matrix,
distance = displacement,
phonopy_obj = Phonopy(cell_obj,
supercell_matrix,
distance = displacement,
symprec = sym)
supercells = phonopy_obj.get_supercells_with_displacements()
directories = []
......@@ -154,7 +154,7 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, tol = 1e-
(supercell_calculated.get_atomic_numbers() == supercell.get_atomic_numbers()).all() and
(abs(supercell_calculated.get_positions()-supercell.get_positions()) < tol).all() and
(abs(supercell_calculated.get_cell()-supercell.get_cell()) < tol).all() ):
# read_aims_output reads in forces from FHI-aims output as list structure,
# read_aims_output reads in forces from FHI-aims output as list structure,
# but further processing below requires numpy array
forces = np.array(supercell_calculated.get_forces())
drift_force = forces.sum(axis=0)
......@@ -178,19 +178,19 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, tol = 1e-
class Get_Properties():
def __init__(self,
hessian = None,
cell = None,
positions = None,
symbols = None,
SC_matrix = None,
symmetry_thresh = None,
displacement = None,
name = None,
metaInfoEnv = None,
def __init__(self,
hessian = None,
cell = None,
positions = None,
symbols = None,
SC_matrix = None,
symmetry_thresh = None,
displacement = None,
name = None,
metaInfoEnv = None,
parser_info = None,
):
#### restoring units
convert_Phi = convert_unit_function('joules*meter**-2', 'eV*angstrom**-2')
convert_angstrom = convert_unit_function('meter', 'angstrom')
......@@ -199,7 +199,7 @@ class Get_Properties():
positions = convert_angstrom(positions)
displacement = convert_angstrom(displacement)
####
#### Constructing phonopy_obj
cell_obj = Atoms(cell = list(cell), symbols= list(symbols), positions= list(positions))
scaled_positions = cell_obj.get_scaled_positions()
......@@ -209,12 +209,12 @@ class Get_Properties():
self.phonopy_obj = phonopy_obj
#### name of the file where the properties are to be stored in
#### name of the file where the properties are to be stored in
self.name = name
self.metaInfoEnv = metaInfoEnv
self.parser_info = parser_info
#### choosing mesh
num_of_atoms = cell_obj.get_number_of_atoms()
mesh_density = 2*80**3/num_of_atoms
......@@ -228,13 +228,13 @@ class Get_Properties():
self.parameters = generate_kPath_ase(cell, symmetry_thresh)
####
#### getting number of atoms
#### getting number of atoms
self.num_of_atoms = num_of_atoms
def post_process_band(self, frequency_unit_factor, parameters = None, is_eigenvectors=False, lookup_labels=False):
phonopy_obj = self.phonopy_obj
......@@ -270,15 +270,15 @@ class Get_Properties():
bands_labels.append(BandStructureLabels.get(label.lower(),label))
else:
bands_labels.append(label)
bs_obj = BandStructure(bands,
phonopy_obj.dynamical_matrix,
bs_obj = BandStructure(bands,
phonopy_obj.dynamical_matrix,
is_eigenvectors=is_eigenvectors,
factor=frequency_unit_factor)
factor=frequency_unit_factor)
freqs = bs_obj.get_frequencies()
return np.array(freqs), np.array(bands), np.array(bands_labels)
def get_dos(self, mesh = None):
phonopy_obj = self.phonopy_obj
if mesh == None:
mesh = self.mesh
......@@ -293,7 +293,7 @@ class Get_Properties():
return f, dos
def get_thermodynamical_properties(self, mesh = None, t_max = None, t_min = None, t_step = None):
phonopy_obj = self.phonopy_obj
if t_max == None:
t_max = 1000
......@@ -311,7 +311,7 @@ class Get_Properties():
JmolToEv = kJmolToEv / 1000
cv = JmolToEv*cv
return T, fe, entropy, cv
def prep_bands(self, Emit, parameters = None):
#name = self.name
......@@ -319,7 +319,7 @@ class Get_Properties():
#parser_info = self.parser_info
freqs, bands, bands_labels = self.post_process_band(VaspToTHz)
#### converting THz to eV
freqs = freqs*THzToEv
####
......@@ -341,9 +341,9 @@ class Get_Properties():
Emit.closeSection("section_k_band_segment", skBands)
Emit.closeSection("section_k_band", skBand)
####
def prep_density_of_states(self, Emit, mesh = None):
#name = self.name
#metaInfoEnv = self.metaInfoEnv
#parser_info = self.parser_info
......@@ -371,7 +371,7 @@ class Get_Properties():
####
def prep_thermodynamical_properties(self, Emit, sSingleConf, mesh = None, t_max = None, t_min = None, t_step = None):
#name = self.name
#metaInfoEnv = self.metaInfoEnv
#parser_info = self.parser_info
......@@ -387,7 +387,7 @@ class Get_Properties():
fe = eVtoJoules(fe)
cv = eVperKtoJoules(cv)
####
#### emitting
frameSeq = Emit.openSection("section_frame_sequence")
Emit.addArrayValues("frame_sequence_local_frames_ref", np.array([sSingleConf]))
......@@ -411,9 +411,9 @@ class Get_Properties():
Emit.closeSection("section_calculation_to_calculation_refs", sCalc)
def emit_properties(self, emit = ["bands", "dos", "thermodynamical_properties"], parameters = None, mesh = None, t_max = None, t_min = None, t_step = None):
#### emit has to be either "bands", "dos", or "thermodynamical_properties" default is all of them
name = self.name
metaInfoEnv = self.metaInfoEnv
parser_info = self.parser_info
......@@ -431,17 +431,17 @@ class Get_Properties():
Emit.closeSection("section_single_configuration_calculation", sSingleConf)
Emit.closeSection("section_run", sRun)
Emit.finishedParsingSession("ParseSuccess", None)
def prem_emit(self,
Emit,
sSingleConf,
emit = ["bands", "dos", "thermodynamical_properties"],
parameters = None,
mesh = None,
t_max = None,
t_min = None,
def prem_emit(self,
Emit,
sSingleConf,
emit = ["bands", "dos", "thermodynamical_properties"],
parameters = None,
mesh = None,
t_max = None,
t_min = None,
t_step = None):
for get in emit:
if get == "bands":
self.prep_bands(Emit, parameters)
......@@ -449,5 +449,5 @@ class Get_Properties():
self.prep_density_of_states(Emit, mesh)
if get == "thermodynamical_properties":
self.prep_thermodynamical_properties(Emit, sSingleConf, mesh, t_max, t_min, t_step)
# Copyright 2016-2018 Fawzi Mohamed, Danio Brambila
#
# 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.
#### phonopy parser written by Hagen-Henrik Kowalski and based on the original work of Joerg Mayer on phonopy-FHI-aims
import numpy as np
from phonopyparser.PhononModulesNomad import *
from fnmatch import fnmatch
import sys
import math
import os
import argparse
import logging
import nomad_meta_info
from phonopy.interface.FHIaims import read_aims, write_aims, read_aims_output
from phonopyparser.con import Control
# Note this Phonopy is the NOMAD-lab version. Not the open source package on PYPI.
from phonopy import Phonopy, __version__
from phonopy.structure.symmetry import Symmetry
from phonopy.file_IO import write_FORCE_CONSTANTS
from phonopy.harmonic.forces import Forces
from phonopy.harmonic.force_constants import get_force_constants
from phonopy.units import *
from nomadcore.unit_conversion.unit_conversion import convert_unit_function
from nomadcore.parser_backend import *
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
phonopy_version = __version__
parser_info = {"name": "parser_phonopy", "version": "1.0"}
metaInfoPath = os.path.normpath(os.path.join(os.path.dirname(
os.path.abspath(nomad_meta_info.__file__)), "phonopy.nomadmetainfo.json"))
metaInfoEnv, warnings = loadJsonFile(
filePath = metaInfoPath, dependencyLoader = None,
extraArgsHandling = InfoKindEl.ADD_EXTRA_ARGS, uri = None)
from phonopy.structure.atoms import PhonopyAtoms as Atoms
def parse_without_class(name, backend, parser_info):
""" Parsing method for phonopy.
Args:
name: file_name to parse
backend: Localbackend object
parser_info: information about parser to be saved.
"""
# Settings that were previously defined in main().
dir_name = os.path.dirname(name)
geometry_file = os.path.join(dir_name, "geometry.in")
cell_obj = read_aims(geometry_file)
cell = cell_obj.get_cell()
positions = cell_obj.get_positions()
symbols = np.array(cell_obj.get_chemical_symbols())
control = Control(file = os.path.join(dir_name, "control.in"))
if (len(control.phonon["supercell"]) == 3):
supercell_matrix = np.diag(control.phonon["supercell"])
elif (len(control.phonon["supercell"]) == 9):
supercell_matrix = np.array(control.phonon["supercell"]).reshape(3,3)
displacement = control.phonon["displacement"]
sym = control.phonon["symmetry_thresh"]
####
#### constructing FORCE_CONSTANTS
set_of_forces, phonopy_obj, Relative_Path = Collect_Forces_aims(
cell_obj, supercell_matrix, displacement, sym, dir_name)
Prep_Path = name.split("phonopy-FHI-aims-displacement-")
Whole_Path = []
for Path in Relative_Path:
Whole_Path.append("%s%s" % (Prep_Path[0], Path))
phonopy_obj.set_forces(set_of_forces)
phonopy_obj.produce_force_constants()
FC2 = phonopy_obj.get_force_constants()
####
#### obtaining information about supercell
super_c=phonopy_obj.supercell
s_cell = super_c.get_cell()
super_pos = super_c.get_positions()
super_sym = np.array(super_c.get_chemical_symbols())
####
#### Converting properties to Si unitis
converter_FC2 = convert_unit_function('eV*angstrom**-2', 'joules*meter**-2')
convert_angstrom = convert_unit_function('angstrom', 'meter')
FC2 = converter_FC2(FC2)
cell = convert_angstrom(cell)
s_cell = convert_angstrom(s_cell)
super_pos = convert_angstrom(super_pos)
positions = convert_angstrom(positions)
displacement = convert_angstrom(displacement)
# Previously was the start of the parser.
pbc = np.array((1, 1, 1), bool)
Parse = backend # Previous dev. called backend Parse.
# Parse = JsonParseEventsWriterBackend(metaInfoEnv)
Parse.startedParsingSession(name, parser_info)
sRun = Parse.openSection("section_run")
Parse.addValue("program_name", "Phonopy")
Parse.addValue("program_version", phonopy_version)
Basesystem = Parse.openSection("section_system")
Parse.addArrayValues("configuration_periodic_dimensions", pbc)
Parse.addArrayValues("atom_labels", symbols)
Parse.addArrayValues("atom_positions", positions)
Parse.addArrayValues("simulation_cell", cell)
Parse.closeSection("section_system", Basesystem)
Supercellsystem = Parse.openSection("section_system")
sysrefs = Parse.openSection("section_system_to_system_refs")
Parse.addValue("system_to_system_kind", "subsystem")
Parse.addValue("system_to_system_ref", Basesystem)
Parse.closeSection("section_system_to_system_refs", sysrefs)
Parse.addArrayValues("configuration_periodic_dimensions", pbc)
Parse.addArrayValues("atom_labels", super_sym)
Parse.addArrayValues("atom_positions", super_pos)
Parse.addArrayValues("simulation_cell", s_cell)
Parse.addArrayValues("SC_matrix", supercell_matrix)
Parse.addValue("x_phonopy_original_system_ref", Basesystem)
Parse.closeSection("section_system", Supercellsystem)
method = Parse.openSection("section_method")
Parse.addValue("x_phonopy_symprec", sym)
Parse.addValue("x_phonopy_displacement", displacement)
Parse.closeSection("section_method", method)
results = Parse.openSection("section_single_configuration_calculation")
Parse.addValue("single_configuration_calculation_to_system_ref", Supercellsystem)
Parse.addValue("single_configuration_to_calculation_method_ref", method)
Parse.addArrayValues("hessian_matrix", FC2)
GP = Get_Properties(FC2, cell, positions, symbols, supercell_matrix, sym, displacement)
GP.prem_emit(Parse, results)
GP.prep_ref(Whole_Path, Parse)
Parse.closeSection("section_single_configuration_calculation", results)
Parse.closeSection("section_run", sRun)
Parse.finishedParsingSession("ParseSuccess", None)
return Parse # Return the local backend to which we have been writing.
class PhonopyParserWrapper():
""" A proper class envolop for running this parser using Noamd-FAIRD infra. """
def __init__(self, backend, **kwargs):
self.backend_factory = backend
def parse(self, mainfile):
logging.info('phonopy parser started')
logging.getLogger('nomadcore').setLevel(logging.WARNING)
backend = self.backend_factory(metaInfoEnv)
# Call the old parser without a class.
parserInfo = parser_info
backend = parse_without_class(mainfile, backend, parserInfo)
return backend
#### determening properties of the undisplaced cell
if __name__ == '__main__':
import sys
parser = argparse.ArgumentParser(description='Parses a phonopy calculation.')
parser.add_argument('mainFileUri',
help='The uri of the main file associated with this calculation.')
parser.add_argument('mainFilePath', default = None,
help='The path to the main file associated with this calculation.')
parser.add_argument('--kind', default = 'FHI-aims', choices = ["FHI-aims"],
help='The kind of phonopy calculation performed')
args = parser.parse_args()
if args.mainFilePath:
mainDir = os.path.dirname(os.path.dirname(os.path.abspath(args.mainFilePath)))
os.chdir(mainDir)
name = args.mainFileUri
cell_obj = read_aims("geometry.in")
cell = cell_obj.get_cell()
positions = cell_obj.get_positions()
symbols = np.array(cell_obj.get_chemical_symbols())
control = Control()
if (len(control.phonon["supercell"]) == 3):
supercell_matrix = np.diag(control.phonon["supercell"])
elif (len(control.phonon["supercell"]) == 9):
supercell_matrix = np.array(control.phonon["supercell"]).reshape(3,3)
displacement = control.phonon["displacement"]
sym = control.phonon["symmetry_thresh"]
####
#### constructing FORCE_CONSTANTS
set_of_forces, phonopy_obj, Relative_Path = Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym)
Prep_Path = name.split("phonopy-FHI-aims-displacement-")
Whole_Path = []
for Path in Relative_Path:
Whole_Path.append("%s%s" % (Prep_Path[0], Path))
phonopy_obj.set_forces(set_of_forces)
phonopy_obj.produce_force_constants()
FC2 = phonopy_obj.get_force_constants()
####
#### obtaining information about supercell
super_c=phonopy_obj.supercell
s_cell = super_c.get_cell()
super_pos = super_c.get_positions()
super_sym = np.array(super_c.get_chemical_symbols())
####
#### Converting properties to Si unitis
converter_FC2 = convert_unit_function('eV*angstrom**-2', 'joules*meter**-2')
convert_angstrom = convert_unit_function('angstrom', 'meter')
FC2 = converter_FC2(FC2)
cell = convert_angstrom(cell)
s_cell = convert_angstrom(s_cell)
super_pos = convert_angstrom(super_pos)
positions = convert_angstrom(positions)
displacement = convert_angstrom(displacement)
#### parsing
parse(name)
# Copyright 2016-2018 Fawzi Mohamed, Danio Brambila
#
# 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.
#### phonopy parser based on the original work of Joerg Mayer on phonopy-FHI-aims
import numpy as np
from phonopyparser.PhononModulesNomad import *
from fnmatch import fnmatch
import sys
import math
import os, logging
from phonopy.interface.FHIaims import read_aims, write_aims, read_aims_output
from phonopyparser.con import Control
from phonopy import Phonopy
from phonopy.structure.symmetry import Symmetry
from phonopy.file_IO import parse_FORCE_CONSTANTS
from phonopy.harmonic.forces import Forces
from phonopy.harmonic.force_constants import get_force_constants
from phonopy.units import *
from phonopy.structure.atoms import Atoms
from nomadcore.unit_conversion.unit_conversion import convert_unit_function
from nomadcore.parser_backend import *
from nomadcore.local_meta_info import loadJsonFile, InfoKindEl
parser_info = {"name": "parser_phonopy", "version": "0.1"}
path = "../../../../nomad-meta-info/meta_info/nomad_meta_info/phonopy.nomadmetainfo.json"
metaInfoPath = os.path.normpath(
os.path.join(os.path.dirname(os.path.abspath(__file__)), path))
metaInfoEnv, warns = loadJsonFile(filePath=metaInfoPath,
dependencyLoader=None,
extraArgsHandling=InfoKindEl.ADD_EXTRA_ARGS,
uri=None)
if __name__ == "__main__":
import sys
name = sys.argv[1]
#### Reading basic properties from JSON
with open(name) as FORCES:
data = json.load(FORCES)
hessian= np.array(data["sections"]["section_single_configuration_calculation-0"]["hessian_matrix"])
SC_matrix = np.array(data["sections"]["section_system-1"]["SC_matrix"])
cell = np.array(data["sections"]["section_system-0"]["simulation_cell"])
symbols = np.array(data["sections"]["section_system-0"]["atom_labels"])
positions = np.array(data["sections"]["section_system-0"]["atom_positions"])
displacement = np.array(data["sections"]["section_method-0"]["x_phonopy_displacement"])
symmetry_thresh = np.array(data["sections"]["section_method-0"]["x_phonopy_symprec"])
####
#### omitting
get_properties = get_properties(hessian, cell, positions, symbols, SC_matrix, symmetry_thresh, displacement, file_name, metaInfoEnv, parser_info)
get_properties.omit_properties()
This diff is collapsed.
# 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.Get_Force_Constants import PhonopyParserWrapper
# Copyright 2016-2018 Fawzi Mohamed, Danio Brambila
#
# 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.
#### phonopy parser based on the original work of Joerg Mayer on phonopy-FHI-aims
import numpy as np
from phonopy.units import VaspToTHz as AimsToTHz, VaspToCm as AimsToCm, VaspToEv as AimsToEv, THzToCm, THzToEv
from phonopy.interface.FHIaims import read_aims, write_aims, read_aims_output
# from phonopy.structure.cells import get_equivalent_smallest_vectors
from phonopy.harmonic.dynamical_matrix import DynamicalMatrix, DynamicalMatrixNAC, get_equivalent_smallest_vectors
from phonopy.structure.cells import get_reduced_bases
import numpy as np
from phonopy import Phonopy
from phonopy.structure.cells import Primitive
class Control:
def __init__(self, file=None):