#
# Copyright (c), 2015-2020, Quantum Espresso Foundation and SISSA (Scuola
# Internazionale Superiore di Studi Avanzati). All rights reserved.
# This file is distributed under the terms of the MIT License. See the
# file 'LICENSE' in the root directory of the present distribution, or
# http://opensource.org/licenses/MIT.
#
# Authors: Davide Brunato, Giovanni Borghi
#
"""
Conversion functions for Quantum Espresso input options.
"""
import logging
from .exceptions import XmlDocumentError
from .utils import to_fortran
logger = logging.getLogger('qeschema')
#
# Other derived values
[docs]def get_starting_magnetization(name, **kwargs):
"""
Build starting magnetization vector from species data.
"""
try:
atomic_species = kwargs['atomic_species']
species = atomic_species['species']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
lines = []
try:
lines.append(' {0}(1)={1}'.format(
name, species.get('starting_magnetization', 0.0)))
except AttributeError:
k = 0
for specie in species:
k += 1
lines.append(' {0}({1})={2}'.format(
name, k, specie.get('starting_magnetization', 0.0)))
return lines
[docs]def get_system_nspin(name, **kwargs):
"""
Get the value for 'nspin' parameter of the SYSTEM namelist.
"""
try:
lsda = kwargs['lsda']
if lsda:
return [' nspin=2']
noncolin = kwargs['noncolin']
if noncolin:
return [' nspin=4']
else:
return [' nspin=1']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
[docs]def set_ibrav_to_zero(name, **_kwargs):
assert isinstance(name, str)
line = ' ibrav=0'
return [line]
[docs]def get_system_eamp(name, **kwargs):
try:
electric_potential = kwargs['electric_potential']
if electric_potential in ('Berry_Phase', 'homogenous_field'):
return []
electric_field_amplitude = kwargs['electric_field_amplitude']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
if electric_potential == 'sawtooth_potential':
return [' eamp={0}'.format(electric_field_amplitude)]
else:
return []
[docs]def get_electrons_efield(name, **kwargs):
try:
electric_potential = kwargs['electric_potential']
if electric_potential in ('Berry_Phase', 'sawtooth_potential'):
return []
electric_field_amplitude = kwargs['electric_field_amplitude']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
if electric_potential == 'homogenous_field':
return [' efield={0}'.format(electric_field_amplitude)]
else:
return []
[docs]def get_system_edir(name, **kwargs):
try:
electric_potential = kwargs['electric_potential']
electric_field_direction = kwargs['electric_field_direction']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
if electric_potential == 'sawtooth_potential':
return [' edir={0}'.format(electric_field_direction)]
else:
return []
[docs]def get_control_gdir(name, **kwargs):
try:
electric_potential = kwargs['electric_potential']
electric_field_direction = kwargs['electric_field_direction']
except KeyError as err:
logger.error("Missing required arguments when building "
"parameter '%s'! %s" % (name, err))
return []
if electric_potential in ('homogenous_field', 'Berry_Phase'):
return [' gdir={0}'.format(electric_field_direction)]
else:
return []
[docs]def get_cell_dofree(name, **kwargs):
assert isinstance(name, str)
cell_dofree_str = "cell_dofree = '%s'"
cell_dofree_all = 'all'
map_data = {
'fix_volume': 'shape',
'fix_area': '2Dshape',
'fix_xy': '2Dxy',
'isotropic': 'volume'
}
for key, val in map_data.items():
if kwargs.get(key):
return [cell_dofree_str % val]
return [cell_dofree_str % cell_dofree_all]
[docs]def neb_set_system_nat(name, **kwargs):
"""
Extract SYSTEM[nat] from the first element of the list of atomic_structure
:param name: Variable name
:param kwargs: list of dictionaries each containing an atomic_structure element
:return: list containing one string to be printed in system name list nat = nat_value
"""
assert isinstance(name, str)
try:
images = kwargs['atomic_structure']
except KeyError:
logger.error('No atomic_structure element found !!!')
return []
try:
nat_value = images[0]['@nat']
except (KeyError, IndexError):
logger.error("error reading nat value from atomic_structure !!!")
return []
return [' nat = {0}'.format(nat_value)]
[docs]def ha2ry(name, **kwargs):
related_tag = kwargs['_related_tag']
value = kwargs[related_tag] * 2.e0
return [' {} = {:12.8f}'.format(name, value)]
[docs]def set_one_amass_line(name, **kwargs):
lines = []
try:
node = kwargs['amass']
value = float(node['$'])
index = node['@atom']
lines.append(' {}({})={:7.3f}'.format(name, index, value))
except TypeError:
for node in kwargs['amass']:
value = float(node['$'])
index = node['@atom']
lines.append(' {}({})={:7.3f}'.format(name, index, value))
return lines
[docs]def set_lda_plus_u_flag(name, **kwargs):
assert isinstance(name, str)
lines = []
related_tag = kwargs['_related_tag']
related_data = kwargs[related_tag]
for value in iter(
related_data if isinstance(related_data, list) else [related_data]):
if value.get('@label') != 'no Hubbard' and value['$'] > 0:
lines.append(f" {name} = .true.")
break
return lines
[docs]def set_boolean_flag(name, **kwargs):
assert isinstance(name, str)
lines = []
related_tag = kwargs['_related_tag']
related_data = kwargs[related_tag]
if related_data is True or isinstance(related_data, str) and \
related_data.strip() in ['true', 'True', 'TRUE', '1']:
lines.append(' %s = .true.' % related_tag)
else:
lines.append(' %s = .false.' % related_tag)
return lines
[docs]def set_what_td_calculation(name, **kwargs):
assert isinstance(name, str)
return [kwargs['whatTD']]