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

Phonopy fix to directory structure.

parent a2f03d73
# 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 PhononModulesNomad import *
import setup_paths
from fnmatch import fnmatch
import sys
import math
import os
import argparse
from phonopy.interface.FHIaims import read_aims, write_aims, read_aims_output
from con import Control
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"}
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)
def parse(name):
pbc = np.array((1, 1, 1), bool)
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)
#### 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 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 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 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.harmonic.dynamical_matrix import get_equivalent_smallest_vectors, DynamicalMatrix, DynamicalMatrixNAC
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):
self.phonon = {}
self.phonon["supercell"] = []
self.phonon["displacement"] = 0.001
self.phonon["symmetry_thresh"] = 1E-6
self.phonon["frequency_unit"] = "cm^-1"
self.phonon["nac"] = {}
if file is None:
self.file = "control.in"
else:
self.file = file
self.read_phonon()
def read_phonon(self):
f = open(self.file, 'r')
try:
for line in f:
if not line:
break
fields = line.split()
nfields = len(fields)
if (nfields > 2) and (fields[0] == "phonon"):
if (fields[1] == "supercell"):
if (nfields >= 11):
s = map(int, fields[2:11])
s = list(s)
Smat = np.array(s).reshape(3,3)
elif (nfields >= 5):
s = map(int, fields[2:5])
s = list(s)
Smat = np.diag(s)
else:
raise Exception("invalid supercell")
det_Smat = np.linalg.det(Smat)
if (det_Smat == 0):
raise Exception("supercell matrix is not invertible")
# this consistency check is not strictly necessary, since int function above used to transform the input
# already throws an exception when decimal numbers are encountered
# keep for consistency (and future changes to that spot?) nevertheless...
elif (abs(det_Smat-round(det_Smat)) > 1.0e-6):
raise Exception("determinant of supercell differs from integer by more than numerical tolerance of 1.0e-6")
self.phonon["supercell"] = s
if (fields[1] == "displacement"):
self.phonon["displacement"] = float(fields[2])
if (fields[1] == "symmetry_thresh"):
self.phonon["symmetry_thresh"] = float(fields[2])
if (fields[1] == "frequency_unit"):
self.phonon["frequency_unit"] = fields[2]
if (fields[1] == "nac") and (len(fields) >= 4):
if (len(fields) >= 7):
delta = tuple(list(map(float, fields[4:7])))
else:
delta = (0.1, 0.1, 0.1)
if (delta[0] == 0.0) and (delta[1] == 0.0) and (delta[2] == 0.0):
raise Exception("evaluation of frequencies with non-analytic corrections must be shifted by delta away from Gamma")
parameters = { "file" : fields[2],
"method" : fields[3].lower(),
"delta" : delta }
self.phonon["nac"].update(parameters)
except Exception:
#print (line,)
#print ("|-> line triggered exception: ") + str(Exception)
raise
# supercell is mandatory for all what follows
if not self.phonon["supercell"]:
raise Exception("no supercell specified in %s" % self.file)
f.close()
# 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.
import sys, os, os.path
baseDir = os.path.dirname(os.path.abspath(__file__))
commonDir = os.path.normpath(os.path.join(baseDir,"../../../../python-common/common/python"))
if not commonDir in sys.path:
sys.path.insert(0, commonDir)
......@@ -130,12 +130,11 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, dir_name,
Relative_Path = []
for directory, supercell in zip(directories, supercells):
aims_out = os.path.join(directory, directory + ".out")
# Added this line for NOMAD-FAIRD
# Added below line for NOMAD-FAIRD
aims_out = os.path.join(dir_name, aims_out)
if not os.path.isfile(aims_out):
logging.warn("!!! file not found: %s" % aims_out)
#print ("!!! file not found: %s" % aims_out)
os.chdir(directory)
os.chdir(os.path.join(dir_name, directory))
cwd = os.getcwd()
con_list = os.listdir(cwd)
check_var = False
......@@ -145,11 +144,9 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, dir_name,
logging.warn(
"!!! WARNING your file seems to have a wrong name proceeding with %s" % aims_out
)
#print ("!!! WARNING your file seems to have a wrong name proceeding with %s" % aims_out)
check_var = True
break
if check_var == False:
#print ("!!! No phonon calculations found")
logging.warn("!!! No phonon calculations found")
sys.exit(1)
os.chdir("../")
......@@ -170,7 +167,6 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, dir_name,
(supercell_calculated.get_atomic_numbers() == supercell.get_atomic_numbers()).all() and
(abs(clean_position(supercell_calculated.get_scaled_positions())-clean_position(supercell.get_scaled_positions())) < tol).all() and
(abs(supercell_calculated.get_cell()-supercell.get_cell()) < tol).all() ):
#print ("!!! there seems to be a rounding error")
logging.warn("!!! there seems to be a rounding error")
forces = np.array(supercell_calculated.get_forces())
drift_force = forces.sum(axis=0)
......@@ -180,7 +176,6 @@ def Collect_Forces_aims(cell_obj, supercell_matrix, displacement, sym, dir_name,
else:
logging.warn(
"!!! calculated varies from expected supercell in FHI-aims output %s" % aims_out)
#print ("!!! calculated varies from expected supercell in FHI-aims output %s" % aims_out)
sys.exit(2)
return set_of_forces, phonopy_obj, Relative_Path
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment