Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
nomad-lab
parser-phonopy
Commits
6af93535
Commit
6af93535
authored
Aug 25, 2020
by
Alvin Noe Ladines
Browse files
Added support for phonony db, switched to metainfo
parent
99f57632
Changes
11
Expand all
Hide whitespace changes
Inline
Side-by-side
phonopyparser/FHIaims.py
0 → 100644
View file @
6af93535
# FHIaims.py - IO routines for phonopy-FHI-aims
# methods compatible with the corresponding ones from ase.io.aims
# only minimal subset of functionality required within phonopy context is implemented
#
# Copyright (C) 2009-2011 Joerg Meyer (jm)
# All rights reserved.
#
# This file is part of phonopy.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
#
# * Redistributions in binary form must reproduce the above copyright
# notice, this list of conditions and the following disclaimer in
# the documentation and/or other materials provided with the
# distribution.
#
# * Neither the name of the phonopy project nor the names of its
# contributors may be used to endorse or promote products derived
# from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
from
phonopy.structure.atoms
import
PhonopyAtoms
def
read_aims
(
filename
):
"""Method to read FHI-aims geometry files in phonopy context."""
lines
=
open
(
filename
,
'r'
).
readlines
()
cell
=
[]
is_frac
=
[]
positions
=
[]
symbols
=
[]
magmoms
=
[]
for
line
in
lines
:
fields
=
line
.
split
()
if
not
len
(
fields
):
continue
if
fields
[
0
]
==
"lattice_vector"
:
vec
=
[
float
(
x
)
for
x
in
fields
[
1
:
4
]]
cell
.
append
(
vec
)
elif
fields
[
0
][
0
:
4
]
==
"atom"
:
if
fields
[
0
]
==
"atom"
:
frac
=
False
elif
fields
[
0
]
==
"atom_frac"
:
frac
=
True
pos
=
[
float
(
x
)
for
x
in
fields
[
1
:
4
]]
sym
=
fields
[
4
]
is_frac
.
append
(
frac
)
positions
.
append
(
pos
)
symbols
.
append
(
sym
)
magmoms
.
append
(
None
)
# implicitly assuming that initial_moments line adhere to FHI-aims geometry.in specification,
# i.e. two subsequent initial_moments lines do not occur
# if they do, the value specified in the last line is taken here - without any warning
elif
fields
[
0
]
==
"initial_moment"
:
magmoms
[
-
1
]
=
float
(
fields
[
1
])
for
(
n
,
frac
)
in
enumerate
(
is_frac
):
if
frac
:
pos
=
[
sum
(
[
positions
[
n
][
l
]
*
cell
[
l
][
i
]
for
l
in
range
(
3
)
]
)
for
i
in
range
(
3
)
]
positions
[
n
]
=
pos
if
None
in
magmoms
:
atoms
=
PhonopyAtoms
(
cell
=
cell
,
symbols
=
symbols
,
positions
=
positions
)
else
:
atoms
=
PhonopyAtoms
(
cell
=
cell
,
symbols
=
symbols
,
positions
=
positions
,
magmoms
=
magmoms
)
return
atoms
def
write_aims
(
filename
,
atoms
):
"""Method to write FHI-aims geometry files in phonopy context."""
lines
=
""
lines
+=
"# geometry.in for FHI-aims
\n
"
lines
+=
"# | generated by phonopy.FHIaims.write_aims()
\n
"
lattice_vector_line
=
"lattice_vector "
+
"%16.16f "
*
3
+
"
\n
"
for
vec
in
atoms
.
get_cell
():
lines
+=
lattice_vector_line
%
tuple
(
vec
)
N
=
atoms
.
get_number_of_atoms
()
atom_line
=
"atom "
+
"%16.16f "
*
3
+
"%s
\n
"
positions
=
atoms
.
get_positions
()
symbols
=
atoms
.
get_chemical_symbols
()
initial_moment_line
=
"initial_moment %16.6f
\n
"
magmoms
=
atoms
.
get_magnetic_moments
()
for
n
in
range
(
N
):
lines
+=
atom_line
%
(
tuple
(
positions
[
n
])
+
(
symbols
[
n
],))
if
magmoms
is
not
None
:
lines
+=
initial_moment_line
%
magmoms
[
n
]
f
=
open
(
filename
,
'w'
)
f
.
write
(
lines
)
f
.
close
()
class
Atoms_with_forces
(
PhonopyAtoms
):
""" Hack to phonopy.atoms to maintain ASE compatibility also for forces."""
def
get_forces
(
self
):
return
self
.
forces
def
read_aims_output
(
filename
):
""" Read FHI-aims output and
return geometry, energy and forces from last self-consistency iteration"""
lines
=
open
(
filename
,
'r'
).
readlines
()
l
=
0
N
=
0
while
l
<
len
(
lines
):
line
=
lines
[
l
]
if
"Number of atoms"
in
line
:
N
=
int
(
line
.
split
()[
5
])
elif
"| Unit cell:"
in
line
:
cell
=
[]
for
i
in
range
(
3
):
l
+=
1
vec
=
[
float
(
x
)
for
x
in
lines
[
l
].
split
()[
1
:
4
]]
cell
.
append
(
vec
)
elif
(
"Atomic structure:"
in
line
)
or
(
"Updated atomic structure:"
in
line
):
if
"Atomic structure:"
in
line
:
i_sym
=
3
i_pos_min
=
4
;
i_pos_max
=
7
elif
"Updated atomic structure:"
in
line
:
i_sym
=
4
i_pos_min
=
1
;
i_pos_max
=
4
l
+=
1
symbols
=
[]
positions
=
[]
for
n
in
range
(
N
):
l
+=
1
fields
=
lines
[
l
].
split
()
sym
=
fields
[
i_sym
]
pos
=
[
float
(
x
)
for
x
in
fields
[
i_pos_min
:
i_pos_max
]]
symbols
.
append
(
sym
)
positions
.
append
(
pos
)
elif
"Total atomic forces"
in
line
:
forces
=
[]
for
i
in
range
(
N
):
l
+=
1
force
=
[
float
(
x
)
for
x
in
lines
[
l
].
split
()[
2
:
5
]]
forces
.
append
(
force
)
l
+=
1
atoms
=
Atoms_with_forces
(
cell
=
cell
,
symbols
=
symbols
,
positions
=
positions
)
atoms
.
forces
=
forces
return
atoms
phonopyparser/Get_Force_Constants.py
deleted
100644 → 0
View file @
99f57632
# 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
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
from
phonopy.structure.atoms
import
PhonopyAtoms
as
Atoms
import
nomad.config
phonopy_version
=
__version__
parser_info
=
{
"name"
:
"parser_phonopy"
,
"version"
:
"1.0"
}
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
(
"phonopy.nomadmetainfo.json"
)
# Call the old parser without a class.
mainDir
=
os
.
path
.
dirname
(
os
.
path
.
dirname
(
os
.
path
.
abspath
(
mainfile
)))
cwd
=
os
.
getcwd
()
os
.
chdir
(
mainDir
)
try
:
return
parse_without_class
(
mainfile
,
backend
)
finally
:
os
.
chdir
(
cwd
)
def
parse_without_class
(
name
,
backend
):
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
=
[]
# Try to resolve references as paths relative to the upload root.
try
:
for
Path
in
Relative_Path
:
abs_path
=
"%s%s"
%
(
Prep_Path
[
0
],
Path
)
rel_path
=
abs_path
.
split
(
nomad
.
config
.
fs
.
staging
+
"/"
)[
1
].
split
(
"/"
,
3
)[
3
]
Whole_Path
.
append
(
rel_path
)
except
Exception
:
logging
.
warn
(
"Could not resolve path to a referenced calculation within the upload."
)
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
pbc
=
np
.
array
((
1
,
1
,
1
),
bool
)
Parse
=
backend
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
backend
phonopyparser/Get_Properties.py
deleted
100644 → 0
View file @
99f57632
# 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
()
phonopyparser/PhononModulesNomad.py
deleted
100644 → 0
View file @
99f57632
This diff is collapsed.
Click to expand it.
phonopyparser/__init__.py
View file @
6af93535
...
...
@@ -12,4 +12,21 @@
# See the License for the specific language governing permissions and
# limitations under the License.
from
phonopyparser.Get_Force_Constants
import
PhonopyParserWrapper
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
()
phonopyparser/__main__.py
0 → 100644
View file @
6af93535
# Copyright 2016-2018 Markus Scheidgen
# 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
import
json
from
phonopyparser
import
PhonopyParser
if
__name__
==
"__main__"
:
archive
=
PhonopyParser
.
main
(
sys
.
argv
[
1
])
json
.
dump
(
archive
.
m_to_dict
(),
sys
.
stdout
,
indent
=
2
)
phonopyparser/
con
.py
→
phonopyparser/
fhiaims_io
.py
View file @
6af93535
...
...
@@ -12,19 +12,16 @@
# 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
# 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
import
math
import
os
import
logging
from
fnmatch
import
fnmatch
from
phonopy
import
Phonopy
from
phonopy.structure.cells
import
Primitive
from
phonopyparser.FHIaims
import
read_aims_output
class
Control
:
def
__init__
(
self
,
file
=
None
):
...
...
@@ -53,7 +50,7 @@ class Control:
if
(
nfields
>=
11
):
s
=
map
(
int
,
fields
[
2
:
11
])
s
=
list
(
s
)
Smat
=
np
.
array
(
s
).
reshape
(
3
,
3
)
Smat
=
np
.
array
(
s
).
reshape
(
3
,
3
)
elif
(
nfields
>=
5
):
s
=
map
(
int
,
fields
[
2
:
5
])
s
=
list
(
s
)
...
...
@@ -66,7 +63,7 @@ class Control:
# 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
):
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"
):
...
...
@@ -82,17 +79,89 @@ class Control:
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
}
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
except
Exception
as
e
:
raise
(
e
)
# supercell is mandatory for all what follows
if
not
self
.
phonon
[
"supercell"
]:
raise
Exception
(
"no supercell specified in %s"
%
self
.
file
)
f
.
close
()
def
clean_position
(
scaled_positions
):
scaled_positions
=
list
(
scaled_positions
)
for
sp
in
range
(
len
(
scaled_positions
)):
for
i
in
range
(
len
(
scaled_positions
[
sp
])):
if
np
.
float
(
np
.
round
(
scaled_positions
[
sp
][
i
],
7
))
>=
1
:
scaled_positions
[
sp
][
i
]
-=
1.0
elif
scaled_positions
[
sp
][
i
]
<=
-
1e-5
:
scaled_positions
[
sp
][
i
]
+=
1.0
scaled_positions
=
np
.
array
(
scaled_positions
)
return
scaled_positions
def
read_forces_aims
(
cell_obj
,
supercell_matrix
,
displacement
,
sym
,
tol
=
1e-6
,
logger
=
None
):
if
logger
is
None
:
logger
=
logging
phonopy_obj
=
Phonopy
(
cell_obj
,
supercell_matrix
,
symprec
=
sym
)
phonopy_obj
.
generate_displacements
(
distance
=
displacement
)
supercells
=
phonopy_obj
.
get_supercells_with_displacements
()
directories
=
[]
digits
=
int
(
math
.
ceil
(
math
.
log
(
len
(
supercells
)
+
1
,
10
)))
+
1
for
i
in
range
(
len
(
supercells
)):
directories
.
append
((
"phonopy-FHI-aims-displacement-%0"
+
str
(
digits
)
+
"d"
)
%
(
i
+
1
))
set_of_forces
=
[]
Relative_Path
=
[]
for
directory
,
supercell
in
zip
(
directories
,
supercells
):
aims_out
=
os
.
path
.
join
(
directory
,
directory
+
".out"
)
if
not
os
.
path
.
isfile
(
aims_out
):
logger
.
warn
(
"!!! file not found: %s"
%
aims_out
)
cwd
=
os
.
getcwd
()
con_list
=
os
.
listdir
(
cwd
)
check_var
=
False
for
name
in
con_list
:
if
fnmatch
(
name
,
'*.out'
):
aims_out
=
'%s/%s'
%
(
directory
,
name
)
logger
.
warn
(
"Your file seems to have a wrong name proceeding with %s"
%
aims_out
)
check_var
=
True
break
if
not
check_var
:
raise
Exception
(
"No phonon calculations found"
)
os
.
chdir
(
"../"
)
Relative_Path
.
append
(
aims_out
)
supercell_calculated
=
read_aims_output
(
aims_out
)
if
(
(
supercell_calculated
.
get_number_of_atoms
()
==
supercell
.
get_number_of_atoms
())
and
(
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,
# but further processing below requires numpy array
forces
=
np
.
array
(
supercell_calculated
.
get_forces
())
drift_force
=
forces
.
sum
(
axis
=
0
)
for
force
in
forces
:
force
-=
drift_force
/
forces
.
shape
[
0
]
set_of_forces
.
append
(
forces
)
elif
(
(
supercell_calculated
.
get_number_of_atoms
()
==
supercell
.
get_number_of_atoms
())
and
(
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
()):
logger
.
warn
(
"!!! there seems to be a rounding error"
)
forces
=
np
.
array
(
supercell_calculated
.
get_forces
())
drift_force
=
forces
.
sum
(
axis
=
0
)
for
force
in
forces
:
force
-=
drift_force
/
forces
.
shape
[
0
]
set_of_forces
.
append
(
forces
)
else
:
raise
Exception
(
"calculated varies from expected supercell in FHI-aims output %s"
%
aims_out
)
return
set_of_forces
,
phonopy_obj
,
Relative_Path
phonopyparser/phonopy_calculators.py
0 → 100644
View file @
6af93535
import
os
import
numpy
as
np
import
phonopy
from
phonopy.units
import
THzToEv
from
phonopyparser.fhiaims_io
import
Control
,
read_forces_aims
from
phonopyparser.phonopy_properties
import
PhononProperties
from
phonopyparser.FHIaims
import
read_aims
from
nomadcore.unit_conversion.unit_conversion
import
convert_unit_function
from
nomad.datamodel.metainfo.public
import
section_run
,
section_system
,
\
section_system_to_system_refs
,
section_method
,
section_single_configuration_calculation
,
\
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
class
PhonopyCalculatorInterface
: