Skip to content
GitLab
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-big-dft
Commits
003edfdc
Commit
003edfdc
authored
Jan 08, 2019
by
Daniel Speckhard
Browse files
Restructured files to remove redundant folders.
parent
1d8d8e17
Changes
10
Hide whitespace changes
Inline
Side-by-side
bigdftparser/__init__.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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
bigdftparser.parser
import
BigDFTParser
bigdftparser/generic/__init__.py
0 → 100644
View file @
003edfdc
bigdftparser/generic/libxc_codes.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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.
LIB_XC_MAPPING
=
{
"001"
:
"LDA_X"
,
"002"
:
"LDA_C_WIGNER"
,
"003"
:
"LDA_C_RPA"
,
"004"
:
"LDA_C_HL"
,
"005"
:
"LDA_C_GL"
,
"006"
:
"LDA_C_XALPHA"
,
"007"
:
"LDA_C_VWN"
,
"008"
:
"LDA_C_VWN_RPA"
,
"009"
:
"LDA_C_PZ"
,
"010"
:
"LDA_C_PZ_MOD"
,
"011"
:
"LDA_C_OB_PZ"
,
"012"
:
"LDA_C_PW"
,
"013"
:
"LDA_C_PW_MOD"
,
"014"
:
"LDA_C_OB_PW"
,
"015"
:
"LDA_C_2D_AMGB"
,
"016"
:
"LDA_C_2D_PRM"
,
"017"
:
"LDA_C_vBH"
,
"018"
:
"LDA_C_1D_CSC"
,
"019"
:
"LDA_X_2D"
,
"020"
:
"LDA_XC_TETER93"
,
"021"
:
"LDA_X_1D"
,
"101"
:
"GGA_X_PBE"
,
"102"
:
"GGA_X_PBE_R"
,
"103"
:
"GGA_X_B86"
,
"104"
:
"GGA_X_B86_R"
,
"105"
:
"GGA_X_B86_MGC"
,
"106"
:
"GGA_X_B88"
,
"107"
:
"GGA_X_G96"
,
"108"
:
"GGA_X_PW86"
,
"109"
:
"GGA_X_PW91"
,
"110"
:
"GGA_X_OPTX"
,
"111"
:
"GGA_X_DK87_R1"
,
"112"
:
"GGA_X_DK87_R2"
,
"113"
:
"GGA_X_LG93"
,
"114"
:
"GGA_X_FT97_A"
,
"115"
:
"GGA_X_FT97_B"
,
"116"
:
"GGA_X_PBE_SOL"
,
"117"
:
"GGA_X_RPBE"
,
"118"
:
"GGA_X_WC"
,
"119"
:
"GGA_X_mPW91"
,
"120"
:
"GGA_X_AM05"
,
"121"
:
"GGA_X_PBEA"
,
"122"
:
"GGA_X_MPBE"
,
"123"
:
"GGA_X_XPBE"
,
"124"
:
"GGA_X_2D_B86_MGC"
,
"125"
:
"GGA_X_BAYESIAN"
,
"126"
:
"GGA_X_PBE_JSJR"
,
"127"
:
"GGA_X_2D_B88"
,
"128"
:
"GGA_X_2D_B86"
,
"129"
:
"GGA_X_2D_PBE"
,
"130"
:
"GGA_C_PBE"
,
"131"
:
"GGA_C_LYP"
,
"132"
:
"GGA_C_P86"
,
"133"
:
"GGA_C_PBE_SOL"
,
"134"
:
"GGA_C_PW91"
,
"135"
:
"GGA_C_AM05"
,
"136"
:
"GGA_C_XPBE"
,
"137"
:
"GGA_C_LM"
,
"138"
:
"GGA_C_PBE_JRGX"
,
"139"
:
"GGA_X_OPTB88_VDW"
,
"140"
:
"GGA_X_PBEK1_VDW"
,
"141"
:
"GGA_X_OPTPBE_VDW"
,
"160"
:
"GGA_XC_LB"
,
"161"
:
"GGA_XC_HCTH_93"
,
"162"
:
"GGA_XC_HCTH_120"
,
"163"
:
"GGA_XC_HCTH_147"
,
"164"
:
"GGA_XC_HCTH_407"
,
"165"
:
"GGA_XC_EDF1"
,
"166"
:
"GGA_XC_XLYP"
,
"167"
:
"GGA_XC_B97"
,
"168"
:
"GGA_XC_B97_1"
,
"169"
:
"GGA_XC_B97_2"
,
"170"
:
"GGA_XC_B97_D"
,
"171"
:
"GGA_XC_B97_K"
,
"172"
:
"GGA_XC_B97_3"
,
"173"
:
"GGA_XC_PBE1W"
,
"174"
:
"GGA_XC_MPWLYP1W"
,
"175"
:
"GGA_XC_PBELYP1W"
,
"176"
:
"GGA_XC_SB98_1a"
,
"177"
:
"GGA_XC_SB98_1b"
,
"178"
:
"GGA_XC_SB98_1c"
,
"179"
:
"GGA_XC_SB98_2a"
,
"180"
:
"GGA_XC_SB98_2b"
,
"181"
:
"GGA_XC_SB98_2c"
,
"401"
:
"HYB_GGA_XC_B3PW91"
,
"402"
:
"HYB_GGA_XC_B3LYP"
,
"403"
:
"HYB_GGA_XC_B3P86"
,
"404"
:
"HYB_GGA_XC_O3LYP"
,
"405"
:
"HYB_GGA_XC_mPW1K"
,
"406"
:
"HYB_GGA_XC_PBEH"
,
"407"
:
"HYB_GGA_XC_B97"
,
"408"
:
"HYB_GGA_XC_B97_1"
,
"410"
:
"HYB_GGA_XC_B97_2"
,
"411"
:
"HYB_GGA_XC_X3LYP"
,
"412"
:
"HYB_GGA_XC_B1WC"
,
"413"
:
"HYB_GGA_XC_B97_K"
,
"414"
:
"HYB_GGA_XC_B97_3"
,
"415"
:
"HYB_GGA_XC_mPW3PW"
,
"416"
:
"HYB_GGA_XC_B1LYP"
,
"417"
:
"HYB_GGA_XC_B1PW91"
,
"418"
:
"HYB_GGA_XC_mPW1PW"
,
"419"
:
"HYB_GGA_XC_mPW3LYP"
,
"420"
:
"HYB_GGA_XC_SB98_1a"
,
"421"
:
"HYB_GGA_XC_SB98_1b"
,
"422"
:
"HYB_GGA_XC_SB98_1c"
,
"423"
:
"HYB_GGA_XC_SB98_2a"
,
"424"
:
"HYB_GGA_XC_SB98_2b"
,
"425"
:
"HYB_GGA_XC_SB98_2c"
,
"201"
:
"MGGA_X_LTA"
,
"202"
:
"MGGA_X_TPSS"
,
"203"
:
"MGGA_X_M06L"
,
"204"
:
"MGGA_X_GVT4"
,
"205"
:
"MGGA_X_TAU_HCTH"
,
"206"
:
"MGGA_X_BR89"
,
"207"
:
"MGGA_X_BJ06"
,
"208"
:
"MGGA_X_TB09"
,
"209"
:
"MGGA_X_RPP09"
,
"231"
:
"MGGA_C_TPSS"
,
"232"
:
"MGGA_C_VSXC"
,
"301"
:
"LCA_OMC"
,
"302"
:
"LCA_LCH"
,
}
bigdftparser/parser.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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
os
import
re
import
logging
import
importlib
from
nomadcore.baseclasses
import
ParserInterface
class
BigDFTParser
(
ParserInterface
):
"""This class handles the initial setup before any parsing can happen. It
determines which version of BigDFT was used to generate the output and then
sets up a correct main parser.
After the implementation has been setup, you can parse the files with
parse().
"""
def
__init__
(
self
,
metainfo_to_keep
=
None
,
backend
=
None
,
default_units
=
None
,
metainfo_units
=
None
,
debug
=
True
,
logger
=
None
,
log_level
=
logging
.
ERROR
,
store
=
True
):
super
(
BigDFTParser
,
self
).
__init__
(
metainfo_to_keep
,
backend
,
default_units
,
metainfo_units
,
debug
,
log_level
,
store
)
if
logger
is
not
None
:
self
.
logger
=
logger
self
.
logger
.
debug
(
'received logger'
)
else
:
self
.
logger
=
logging
.
getLogger
(
__name__
)
def
setup_version
(
self
):
"""Setups the version by looking at the output file and the version
specified in it.
"""
# Search for the BigDFT version specification. The correct parser is
# initialized based on this information.
regex_version
=
re
.
compile
(
" Version Number\s+: (\d\.\d)"
)
version_id
=
None
with
open
(
self
.
parser_context
.
main_file
,
'r'
)
as
outputfile
:
header
=
outputfile
.
read
(
50
*
80
)
for
line
in
header
.
split
(
"
\n
"
):
# Look for version definition
result_version
=
regex_version
.
match
(
line
)
if
result_version
:
version_id
=
result_version
.
group
(
1
).
replace
(
'.'
,
''
)
if
version_id
is
None
:
msg
=
"Could not find a version specification from the given main file."
self
.
logger
.
exception
(
msg
)
raise
RuntimeError
(
msg
)
# Setup the root folder to the fileservice that is used to access files
dirpath
,
filename
=
os
.
path
.
split
(
self
.
parser_context
.
main_file
)
dirpath
=
os
.
path
.
abspath
(
dirpath
)
self
.
parser_context
.
file_service
.
setup_root_folder
(
dirpath
)
self
.
parser_context
.
file_service
.
set_file_id
(
filename
,
"output"
)
# Setup the correct main parser based on the version id. If no match
# for the version is found, use the main parser for NWChem 6.6
self
.
setup_main_parser
(
version_id
)
def
get_metainfo_filename
(
self
):
return
"big_dft.nomadmetainfo.json"
def
get_parser_info
(
self
):
return
{
'name'
:
'big-dft-parser'
,
'version'
:
'1.0'
}
def
setup_main_parser
(
self
,
version_id
):
# Currently the version id is a pure integer, so it can directly be mapped
# into a package name.
base
=
"bigdftparser.versions.bigdft{}.mainparser"
.
format
(
version_id
)
parser_module
=
None
parser_class
=
None
try
:
parser_module
=
importlib
.
import_module
(
base
)
except
ImportError
:
self
.
logger
.
warning
(
"Could not find a parser for version '{}'. Trying to default to the base implementation for BigDFT 1.8.0"
.
format
(
version_id
))
base
=
"bigdftparser.versions.bigdft18.mainparser"
try
:
parser_module
=
importlib
.
import_module
(
base
)
except
ImportError
:
self
.
logger
.
exception
(
"Could not find the module '{}'"
.
format
(
base
))
raise
try
:
class_name
=
"BigDFTMainParser"
parser_class
=
getattr
(
parser_module
,
class_name
)
except
AttributeError
:
self
.
logger
.
exception
(
"A parser class '{}' could not be found in the module '[]'."
.
format
(
class_name
,
parser_module
))
raise
self
.
main_parser
=
parser_class
(
self
.
parser_context
)
bigdftparser/scalainterface.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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.
"""
This is the access point to the parser for the scala layer in the
nomad project.
"""
from
__future__
import
absolute_import
import
sys
import
setup_paths
from
nomadcore.parser_backend
import
JsonParseEventsWriterBackend
from
bigdftparser
import
BigDFTParser
if
__name__
==
"__main__"
:
# Initialise the parser with the main filename and a JSON backend
main_file
=
sys
.
argv
[
1
]
parser
=
BigDFTParser
(
backend
=
JsonParseEventsWriterBackend
)
parser
.
parse
(
main_file
)
bigdftparser/setup_paths.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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.
"""
Setups the python-common library in the PYTHONPATH system variable.
"""
import
sys
import
os
import
os.path
baseDir
=
os
.
path
.
dirname
(
os
.
path
.
abspath
(
__file__
))
commonDir
=
os
.
path
.
normpath
(
os
.
path
.
join
(
baseDir
,
"../../../../../python-common/common/python"
))
parserDir
=
os
.
path
.
normpath
(
os
.
path
.
join
(
baseDir
,
"../../parser-big-dft"
))
# Using sys.path.insert(1, ...) instead of sys.path.insert(0, ...) based on
# this discusssion:
# http://stackoverflow.com/questions/10095037/why-use-sys-path-appendpath-instead-of-sys-path-insert1-path
if
commonDir
not
in
sys
.
path
:
sys
.
path
.
insert
(
1
,
commonDir
)
sys
.
path
.
insert
(
1
,
parserDir
)
bigdftparser/tools/__init__.py
0 → 100644
View file @
003edfdc
bigdftparser/versions/__init__.py
0 → 100644
View file @
003edfdc
bigdftparser/versions/bigdft18/__init__.py
0 → 100644
View file @
003edfdc
bigdftparser/versions/bigdft18/mainparser.py
0 → 100644
View file @
003edfdc
# Copyright 2016-2018 Lauri Himanen, Fawzi Mohamed
#
# 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
logging
import
numpy
as
np
from
yaml
import
Loader
,
YAMLError
from
yaml
import
ScalarNode
,
SequenceNode
,
MappingNode
,
MappingEndEvent
from
nomadcore.baseclasses
import
AbstractBaseParser
from
bigdftparser.generic.libxc_codes
import
LIB_XC_MAPPING
LOGGER
=
logging
.
getLogger
(
"nomad"
)
class
BigDFTMainParser
(
AbstractBaseParser
):
"""The main parser class that is called for all run types. Parses the NWChem
output file.
"""
def
__init__
(
self
,
parser_context
):
"""
"""
super
(
BigDFTMainParser
,
self
).
__init__
(
parser_context
)
# Map keys in the output to funtions that handle the values
self
.
key_to_funct_map
=
{
"Version Number"
:
lambda
x
:
self
.
backend
.
addValue
(
"program_version"
,
x
),
"Atomic structure"
:
self
.
atomic_structure
,
"Sizes of the simulation domain"
:
self
.
simulation_domain
,
"Atomic System Properties"
:
self
.
atomic_system_properties
,
"dft"
:
self
.
dft
,
"DFT parameters"
:
self
.
dft_parameters
,
"Ground State Optimization"
:
self
.
ground_state_optimization
,
"Atomic Forces (Ha/Bohr)"
:
self
.
atomic_forces
,
"Energy (Hartree)"
:
lambda
x
:
self
.
backend
.
addRealValue
(
"energy_total"
,
float
(
x
),
unit
=
"hartree"
),
}
def
parse
(
self
,
filepath
):
"""The output file of a BigDFT run is a YAML document. Here we directly
parse this document with an existing YAML library, and push its
contents into the backend. This function will read the document in
smaller pieces, thus preventing the parser from opening too large files
directly into memory.
"""
self
.
prepare
()
self
.
print_json_header
()
with
open
(
filepath
,
"r"
)
as
fin
:
try
:
# Open default sections and output default information
section_run_id
=
self
.
backend
.
openSection
(
"section_run"
)
section_system_id
=
self
.
backend
.
openSection
(
"section_system"
)
section_method_id
=
self
.
backend
.
openSection
(
"section_method"
)
section_scc_id
=
self
.
backend
.
openSection
(
"section_single_configuration_calculation"
)
self
.
backend
.
addValue
(
"program_name"
,
"BigDFT"
)
self
.
backend
.
addValue
(
"electronic_structure_method"
,
"DFT"
)
self
.
backend
.
addValue
(
"program_basis_set_type"
,
"real-space grid"
)
self
.
backend
.
addValue
(
"single_configuration_calculation_to_system_ref"
,
section_system_id
)
self
.
backend
.
addValue
(
"single_configuration_to_calculation_method_ref"
,
section_method_id
)
loader
=
Loader
(
fin
)
generator
=
self
.
generate_root_nodes
(
loader
)
# Go through all the keys in the mapping, and call an appropriate
# function on the value.
for
key
,
value
in
generator
:
function
=
self
.
key_to_funct_map
.
get
(
key
)
if
function
is
not
None
:
function
(
value
)
# Close default sections
self
.
backend
.
closeSection
(
"section_single_configuration_calculation"
,
section_scc_id
)
self
.
backend
.
closeSection
(
"section_method"
,
section_method_id
)
self
.
backend
.
closeSection
(
"section_system"
,
section_system_id
)
self
.
backend
.
closeSection
(
"section_run"
,
section_run_id
)
except
YAMLError
:
raise
Exception
(
"There was a syntax error in the BigDFT YAML output file."
)
self
.
print_json_footer
()
def
generate_root_nodes
(
self
,
loader
):
# Ignore the first two events
loader
.
get_event
()
# StreamStarEvetn
loader
.
get_event
()
# DocumentStartEvent
start_event
=
loader
.
get_event
()
# MappingStartEvent
tag
=
start_event
.
tag
# This is the root mapping that contains everything
node
=
MappingNode
(
tag
,
[],
start_event
.
start_mark
,
None
,
flow_style
=
start_event
.
flow_style
)
while
not
loader
.
check_event
(
MappingEndEvent
):
key
=
loader
.
construct_scalar
(
loader
.
compose_node
(
node
,
None
))
value
=
loader
.
compose_node
(
node
,
key
)
if
isinstance
(
value
,
MappingNode
):
value
=
loader
.
construct_mapping
(
value
,
deep
=
True
)
elif
isinstance
(
value
,
SequenceNode
):
value
=
loader
.
construct_sequence
(
value
,
deep
=
True
)
elif
isinstance
(
value
,
ScalarNode
):
value
=
loader
.
construct_scalar
(
value
)
yield
(
key
,
value
)
#===========================================================================
# The following functions handle the different sections in the output
def
ground_state_optimization
(
self
,
value
):
subspace_optimization
=
value
[
0
][
"Hamiltonian Optimization"
]
subspace_optimization
=
subspace_optimization
[
0
][
"Subspace Optimization"
]
wavefunction_iterations
=
subspace_optimization
[
"Wavefunctions Iterations"
]
n_iterations
=
len
(
wavefunction_iterations
)
self
.
backend
.
addValue
(
"number_of_scf_iterations"
,
n_iterations
)
for
iteration
in
wavefunction_iterations
:
scf_id
=
self
.
backend
.
openSection
(
"section_scf_iteration"
)
energies
=
iteration
[
"Energies"
]
# ekin = energies["Ekin"]
# epot = energies["Epot"]
# enl = energies["Enl"]
# eh = energies["EH"]
# gradient = iteration["gnrm"]
exc
=
energies
.
get
(
"EXC"
)
# Use get instead, because this value is not always present
evxc
=
energies
.
get
(
"EvXC"
)
# Use get instead, because this value is not always present
etotal
=
iteration
[
"EKS"
]
energy_change
=
iteration
[
"D"
]
self
.
backend
.
addRealValue
(
"energy_total_scf_iteration"
,
etotal
,
unit
=
"hartree"
)
if
exc
is
not
None
:
self
.
backend
.
addRealValue
(
"energy_XC_scf_iteration"
,
exc
,
unit
=
"hartree"
)
if
evxc
is
not
None
:
self
.
backend
.
addRealValue
(
"energy_XC_potential_scf_iteration"
,
evxc
,
unit
=
"hartree"
)
self
.
backend
.
addRealValue
(
"energy_change_scf_iteration"
,
energy_change
,
unit
=
"hartree"
)
self
.
backend
.
closeSection
(
"section_scf_iteration"
,
scf_id
)
def
atomic_structure
(
self
,
value
):
np_positions
=
[]
np_labels
=
[]
positions
=
value
[
"Positions"
]
for
position
in
positions
:
np_positions
.
append
(
*
position
.
values
())
np_labels
.
append
(
*
position
.
keys
())
np_positions
=
np
.
array
(
np_positions
)
np_labels
=
np
.
array
(
np_labels
)
self
.
backend
.
addArrayValues
(
"atom_positions"
,
np_positions
,
unit
=
"angstrom"
)
self
.
backend
.
addArrayValues
(
"atom_labels"
,
np_labels
)
def
simulation_domain
(
self
,
value
):
simulation_cell
=
np
.
diag
(
value
[
"Angstroem"
])
self
.
backend
.
addArrayValues
(
"simulation_cell"
,
simulation_cell
,
unit
=
"angstrom"
)
def
atomic_system_properties
(
self
,
value
):
# Number of atoms
n_atoms
=
value
[
"Number of atoms"
]
self
.
backend
.
addValue
(
"number_of_atoms"
,
n_atoms
)
# Periodicity
boundary
=
value
[
"Boundary Conditions"
]
if
boundary
==
"Free"
:
periodic_dimensions
=
np
.
array
([
False
,
False
,
False
])
elif
boundary
==
"Periodic"
:
periodic_dimensions
=
np
.
array
([
True
,
True
,
True
])
elif
boundary
==
"Surface"
:
periodic_dimensions
=
np
.
array
([
True
,
False
,
True
])
else
:
raise
Exception
(
"Unknown boundary condtions."
)
self
.
backend
.
addArrayValues
(
"configuration_periodic_dimensions"
,
periodic_dimensions
)
def
dft
(
self
,
value
):
# Total_charge
charge
=
value
[
"qcharge"
]
self
.
backend
.
addValue
(
"total_charge"
,
charge
)
# SCF options
max_iter
=
value
[
"itermax"
]
self
.
backend
.
addValue
(
"scf_max_iteration"
,
max_iter
)
# Spin channels
n_spin
=
value
[
"nspin"
]
self
.
backend
.
addValue
(
"number_of_spin_channels"
,
n_spin
)
def
atomic_forces
(
self
,
value
):
forces
=
[]
for
force
in
value
:
forces
.
append
(
*
force
.
values
())
forces
=
np
.
array
(
forces
)
self
.
backend
.
addArrayValues
(
"atom_forces"
,
forces
,
unit
=
"hartree/bohr"
)
def
dft_parameters
(
self
,
value
):
# XC functional
exchange_settings
=
value
[
"eXchange Correlation"
]
xc_id
=
exchange_settings
[
"XC ID"
]
# LibXC codes, see http://bigdft.org/Wiki/index.php?title=XC_codes
if
xc_id
<
0
:
xc_parts
=
[]
xc_id_str
=
str
(
xc_id
)[
1
:]
xc_id_str_len
=
len
(
xc_id_str
)
if
xc_id_str_len
<=
3
:
xc_id_str
=
"0"
*
(
3
-
xc_id_str_len
)
+
xc_id_str
xc_parts
.
append
(
xc_id_str
)
elif
xc_id_str_len
==
6
:
xc_parts
.
append
(
xc_id_str
[:
3
])
xc_parts
.
append
(
xc_id_str
[
3
:])
xc
=
[]
for
part
in
xc_parts
:
xc1
=
LIB_XC_MAPPING
.
get
(
part
)
if
xc1
is
not
None
:
xc
.
append
(
xc1
)
else
:
raise
Exception
(
"Unknown LibXC functional number: '{}'"
.
format
(
part
))
# ABINIT codes, see
# http://www.tddft.org/programs/octopus/wiki/index.php/Developers_Manual:ABINIT
# and
# http://bigdft.org/Wiki/index.php?title=XC_codes
else
:
mapping
=
{
1
:
[
"LDA_XC_TETER93"
],
# 2: ["LDA_C_PZ"], # Not really sure...
# 3: Unknown
# 4: ["LDA_C_WIGNER"], # Not really sure...
# 5: ["LDA_C_HL"], # Not really sure...
# 6: ["LDA_C_XALPHA"], # Not really sure...
# 7: ["LDA_XC_PW"], # Not really sure...
# 8: ["LDA_X_PW"], # Not really sure...
# 9: ["LDA_X_PW", "LDA_C_RPA"], # Not really sure...
# 10: Internal
11
:
[
"GGA_C_PBE"
,
"GGA_X_PBE"
],
12
:
[
"GGA_X_PBE"
],
# 13: ["GGA_C_PBE","GGA_X_LB"], # Not really sure...
# 14: ["GGA_C_PBE","GGA_X_PBE_R"], # Not really sure...
15
:
[
"GGA_C_PBE"
,
"GGA_X_RPBE"
],
16
:
[
"GGA_XC_HCTH_93"
],
17
:
[
"GGA_XC_HCTH_120"
],
# 20: Unknown
# 21: Unknown
# 22: Unknown
# 23: ["GGA_X_WC"], # Not really sure...
# 24: ["GGA_X_C09X"], # Not really sure...
# 25: Internal
26
:
[
"GGA_XC_HCTH_147"
],
27
:
[
"GGA_XC_HCTH_407"
],
# 28: Internal
100
:
[
"HF_X"
],
}
xc
=
mapping
.
get
(
xc_id
)
# Create the XC sections and a summary
if
xc
is
None
:
raise
Exception
(
"Unknown functional number: '{}'"
.
format
(
xc_id
))
sorted_xc
=
sorted
(
xc
)
summary
=
""
n_names
=
len
(
sorted_xc
)
for
i_name
,
name
in
enumerate
(
sorted_xc
):
weight
=
1.0
xc_id
=
self
.
backend
.
openSection
(
"section_XC_functionals"
)
self
.
backend
.
addValue
(
"XC_functional_name"
,
name
)
self
.
backend
.
addValue
(
"XC_functional_weight"
,
weight
)
self
.
backend
.
closeSection
(
"section_XC_functionals"
,
xc_id
)
summary
+=
"{}*{}"
.
format
(
weight
,
name
)
if
i_name
+
1
!=
n_names
:
summary
+=
"_"