Skip to content

Commit

Permalink
Merge pull request #37 from QEF/develop
Browse files Browse the repository at this point in the history
Develop 2 master
  • Loading branch information
brunato authored Apr 21, 2023
2 parents cf63ab3 + 75db960 commit 39adc1d
Show file tree
Hide file tree
Showing 36 changed files with 3,285 additions and 75 deletions.
3 changes: 2 additions & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
strategy:
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
python-version: ['3.7', '3.8', '3.9', '3.10']
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11']
steps:
- uses: actions/checkout@v2
- name: Set up Python
Expand All @@ -29,6 +29,7 @@ jobs:
python -m pip install --upgrade pip
pip install -r requirements-dev.txt
- name: Lint with flake8
if: ${{ matrix.python-version != '3.7' }}
run: |
flake8 qeschema --max-line-length=100 --statistics
- name: Run tests
Expand Down
8 changes: 4 additions & 4 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,10 @@ Loaded data can be decoded to Python data dictionary or written to JSON or YAML
Authors
-------
Davide Brunato
Pietro Delugas
Giovanni Borghi
Alexandr Fonari
* Davide Brunato
* Pietro Delugas
* Giovanni Borghi
* Alexandr Fonari


License
Expand Down
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,11 @@
# -- Project information -----------------------------------------------------

project = 'qeschema'
copyright = '2015-2022, Quantum Espresso Foundation and SISSA'
copyright = '2015-2023, Quantum Espresso Foundation and SISSA'
author = 'Davide Brunato, Pietro Delugas'

# The full version, including alpha/beta/rc tags
release = '1.4.0'
release = '1.5.0'


# -- General configuration ---------------------------------------------------
Expand Down
18 changes: 10 additions & 8 deletions qeschema/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,20 @@
# Authors: Davide Brunato
#
from .documents import XmlDocument, QeDocument, PwDocument, PhononDocument, \
NebDocument, TdDocument, TdSpectrumDocument, XSpectraDocument
from .converters import RawInputConverter, PwInputConverter, PhononInputConverter, \
NebInputConverter, TdInputConverter, TdSpectrumInputConverter, XSpectraInputConverter
NebDocument, TdDocument, TdSpectrumDocument, XSpectraDocument, EPWDocument
from .converters import RawInputConverter, PwInputConverter, \
PhononInputConverter, NebInputConverter, TdInputConverter, \
TdSpectrumInputConverter, XSpectraInputConverter, EPWInputConverter
from .exceptions import QESchemaError, XmlDocumentError
from .utils import set_logger

__version__ = '1.4.0'
__version__ = '1.5.0'

__all__ = [
'XmlDocument', 'QeDocument', 'PwDocument', 'PhononDocument', 'NebDocument',
'TdDocument', 'TdSpectrumDocument', 'RawInputConverter', 'PwInputConverter',
'PhononInputConverter', 'TdInputConverter', 'TdSpectrumInputConverter',
'NebInputConverter', 'QESchemaError', 'XmlDocumentError', 'set_logger', 'hdf5',
'XSpectraDocument', 'XSpectraInputConverter'
'TdDocument', 'TdSpectrumDocument', 'EPWDocument', 'RawInputConverter',
'PwInputConverter', 'PhononInputConverter', 'TdInputConverter',
'TdSpectrumInputConverter', 'NebInputConverter', 'QESchemaError',
'XmlDocumentError', 'set_logger', 'hdf5', 'XSpectraDocument',
'XSpectraInputConverter', 'EPWInputConverter'
]
91 changes: 78 additions & 13 deletions qeschema/cards.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
Conversion functions for Quantum Espresso cards.
"""
import logging
from typing import Union, List

logger = logging.getLogger('qeschema')

Expand Down Expand Up @@ -130,24 +129,19 @@ def get_atomic_constraints_card(name, **kwargs):
:return: List of strings
"""
try:
num_of_constraints = kwargs['num_of_constraints']
tolerance = kwargs['tolerance']
atomic_constraints = kwargs['atomic_constraints']
num_of_constraints = kwargs['atomic_constraints']['num_of_constraints']
tolerance = kwargs['atomic_constraints']['tolerance']
atomic_constraints = kwargs['atomic_constraints']['atomic_constraint']
except KeyError:
logger.error("Missing required arguments when building CONSTRAINTS card!")
return []

lines = [name, '{0} {1}'.format(num_of_constraints, tolerance)]
lines = [name, f"{num_of_constraints} {tolerance}"]
for constraint in atomic_constraints:
constr_parms = constraint['constr_parms'] # list with 4 float items
constr_parms.extend([0] * max(0, 4 - len(constr_parms)))
constr_parms = constraint['constr_parms'] # list with at most 4 float items
constr_type = constraint['constr_type'] # string
constr_target = constraint['constr_target'] # float
lines.append('{0} {1} {2}'.format(
constr_type,
' '.join([str(item) for item in constr_parms]),
constr_target
))
constr_target = constraint.get('constr_target', "") # float or empty
lines.append(f"{constr_type} {' '.join([str(_) for _ in constr_parms])} {constr_target}")
return lines


Expand Down Expand Up @@ -195,6 +189,77 @@ def get_k_points_card(name, **kwargs):
return lines


def get_hubbard_card(name, **kwargs):
"""
writes the hubbard card for new format
"""
try:
new_format = kwargs['dftU']['@new_format']
except KeyError:
new_format = False
if not new_format:
return []
try:
dftu = kwargs['dftU']
except KeyError as err:
logger.error("Missing required argument %s when building "
"parameter %r", str(err), name)
return []

projtype = kwargs.get('U_projection_type', 'atomic')
lines = [f"{name} {projtype}"]
for tag in iter(['U', 'J0', 'alpha', 'beta']):
lines.extend(_hubbard_lines(dftu, tag))
for tag in iter(['J', 'U2', 'V']):
lines.extend(_hubbard_special_lines(dftu, tag))
return lines


def _hubbard_lines(dftu, tag):
related_data = dftu.get(f"Hubbard_{tag}", [])
lines = []
for value in iter(related_data if isinstance(related_data, list) else [related_data]):
specie = value['@specie']
label = value['@label']
if label != 'no Hubbard':
lines.append(f"{tag} {specie}-{label} {value['$']:8.3f}")
return lines


def _hubbard_special_lines(dftu, tag):
related_data = dftu.get(f"Hubbard_{tag}", [])
llabels = ['s', 'p', 'd', 'f']
lines = []
for value in iter(related_data if isinstance(related_data, list) else [related_data]):
specie = value['@specie']
label = value.get('@label', 'not found')
if label != 'no Hubbard':
if tag == 'J':
lines.append(f"J {specie}-{label} {value['$'][0]:8.3f}")
if 'd' in label:
lines.append(f"B {specie}-{label} {value['$'][1]:8.3f}")
elif 'f' in label:
lines.extend([f"E2 {specie}-{label} {value['$'][1]:8.3f}",
f"E3 {specie}-{label} {value['$'][2]:8.3f}"])
elif tag == 'U2':
background = value['@background']
if label == 'not found':
def labnl(nnum, lnum):
return f"{nnum}{llabels[lnum-1]}"

label = labnl(value['n2_number'], value['l2_number'])
if 'two' in background:
label = f"{label}-{labnl(value['n3_number'],value['l3_number'])}"
lines.append(f"U {specie}-{label} {value['$']:8.3f}")
elif tag == 'V':
speclab1 = f"{value['@specie1']}-{value['@label1']}"
speclab2 = f"{value['@specie2']}-{value['@label2']}"
index1 = value['@index1']
index2 = value['@index2']
lines.append(f"{tag} {speclab1} {speclab2} {index1} {index2} {value['$']:8.3f}")
return lines


def get_atomic_forces_card(name, **kwargs):
"""
Convert XML data to ATOMIC_FORCES card
Expand Down
143 changes: 130 additions & 13 deletions qeschema/converters.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

FCP_NAMELIST = 'FCP'
PH_NAT_TODO_CARD = 'ph_nat_todo_card'
OPTIONAL_CARDS = {PH_NAT_TODO_CARD}
OPTIONAL_CARDS = {PH_NAT_TODO_CARD, "CONSTRAINTS", "HUBBARD", "SOLVENTS"}


def conversion_maps_builder(template_map):
Expand Down Expand Up @@ -363,27 +363,42 @@ class PwInputConverter(RawInputConverter):
'ecutvcut': ('SYSTEM[ecutvcut]', options.ha2ry, None)
},
'dftU': {
'lda_plus_u_kind': 'SYSTEM[lda_plus_u_kind]',
'@new_format': [('HUBBARD', cards.get_hubbard_card, None),
('SYSTEM[lda_plus_u_kind]', options.set_lda_plus_u_kind, None),
('SYSTEM[lda_plus_u]', options.set_lda_plus_u_flag, None),
('SYSTEM[Hubbard_U]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
('SYSTEM[U_projection_type]', options.set_u_projection_type, None)],
'lda_plus_u_kind': ('SYSTEM[lda_plus_u_kind]', options.set_lda_plus_u_kind, None),
'Hubbard_U': {
'$': [('SYSTEM[Hubbard_U]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None),
('SYSTEM[lda_plus_u]', options.set_lda_plus_u_flag, None)]
},
'Hubbard_J0': {
'$': ('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_J0]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_alpha': {
'$': ('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_alpha]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_beta': {
'$': ('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_beta]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'Hubbard_J': {
'$': ('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
'$': [('SYSTEM[Hubbard_J]', options.get_specie_related_values, None),
('HUBBARD', cards.get_hubbard_card, None)]
},
'starting_ns': {
'$': ('SYSTEM[starting_ns_eigenvalue]', options.get_specie_related_values, None)
},
'U_projection_type': 'SYSTEM[U_projection_type]',
'U_projection_type': ('SYSTEM[U_projection_type]',
options.set_u_projection_type, None)
},
'vdW': {
'vdw_corr': 'SYSTEM[vdw_corr]',
Expand Down Expand Up @@ -561,7 +576,7 @@ def __init__(self, **kwargs):
input_namelists=('CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL',
FCP_NAMELIST),
input_cards=('ATOMIC_SPECIES', 'ATOMIC_POSITIONS', 'K_POINTS',
'CELL_PARAMETERS', 'ATOMIC_FORCES')
'CELL_PARAMETERS', 'ATOMIC_FORCES', 'CONSTRAINTS', 'SOLVENTS', 'HUBBARD')
)
if 'xml_file' in kwargs:
self._input['CONTROL']['input_xml_schema_file'] = "{!r}".format(
Expand All @@ -578,7 +593,7 @@ class PhononInputConverter(RawInputConverter):
"""
PHONON_TEMPLATE_MAP = {
'xq': {
'$': ('qPointsSpecs', cards.get_qpoints_card, None),
'$': ('qPointsSpecs', cards.get_qpoints_card, None),
},
'scf_ph': {
'tr2_ph': "INPUTPH[tr2_ph]",
Expand Down Expand Up @@ -741,7 +756,7 @@ def __init__(self, **_kwargs):
*conversion_maps_builder(self.NEB_TEMPLATE_MAP),
input_namelists=('PATH', 'CONTROL', 'SYSTEM', 'ELECTRONS', 'IONS', 'CELL'),
input_cards=('CLIMBING_IMAGES', 'ATOMIC_SPECIES', 'ATOMIC_POSITIONS', 'K_POINTS',
'CELL_PARAMETERS', 'ATOMIC_FORCES')
'CELL_PARAMETERS', 'ATOMIC_FORCES', 'CONSTRAINTS')
)

def get_qe_input(self):
Expand Down Expand Up @@ -851,9 +866,7 @@ def get_qe_input(self):
Overrides superclass get_qe_input with use_defaults set to False.
:return: the input as obtained from its input builder
"""
temp = super(TdInputConverter, self).get_qe_input().split('\n')
for i, j in enumerate(temp):
print(i, " - ", j)
temp = super().get_qe_input().split('\n')
td = temp[1]
start = temp.index('&lr_input')
end = start + temp[start:].index('/')
Expand Down Expand Up @@ -985,3 +998,107 @@ def __init__(self, **_kwargs):
input_namelists=('input_xspectra', 'plot', 'pseudos', 'cut_occ'),
input_cards=("K_POINTS",)
)


class EPWInputConverter(RawInputConverter):
"""
converts the XML input file for EPW to the namelist format
expected by epw.x
"""
EPW_TEMPLATE_MAP = {
'control_variables': {
'prefix': "inputepw[prefix]",
'outdir': "inputepw[outdir]",
'iverbosity': "inputepw[iverbosity]",
'dvscf_dir': "inputepw[dvscf_dir]",
'filukk': "inputepw[filukk]",
'elph': "inputepw[elph]",
'ep_coupling': "inputepw[ep_coupling]",
'elecselfen': "inputepw[elecselfen]",
'phonselfen': "inputepw[phonselfen]",
'lindabs': "inputepw[lindabs]",
'band_plot': "inputepw[band_plot]",
'fermi_plot': "inputepw[fermi_plot]",
'cumulant': "inputepw[cumulant]",
'prtgkk': "inputepw[prtgkk]",
'epbread': "inputepw[epbread]",
'epbwrite': "inputepw[epbwrite]",
'epwread': "inputepw[epwread]",
'epwwrite': "inputepw[epwwrite]",
'ephwrite': "inputepw[ephwrite]",
'eig_read': "inputepw[eig_read]",
'delta_approx': "inputepw[delta_approx]",
'eps_acustic': "inputepw[eps_acustic]",
'etf_mem': "inputepw[etcmem]",
'nbndsub': "inputepw[nbndsub]",
'nq1': "inputepw[nq1]",
'nq2': "inputepw[nq2]",
'nq3': "inputepw[nq3]",
'nk1': "inputepw[nk1]",
'nk2': "inputepw[nk2]",
'nk3': "inputepw[nk3]",
'nqf1': "inputepw[nqf1]",
'nqf2': "inputepw[nqf2]",
'nqf3': "inputepw[nqf3]",
'nkf1': "inputepw[nkf1]",
'nkf2': "inputepw[nkf2]",
'nkf3': "inputepw[nkf3]",
'mp_mesh_k': "inputepw[mp_mesh_k]",
'filqf': "inputepw[filqf]",
'filkf': "inputepw[filkf]",
'vme': "inputepw[vme]",
'degaussw': "inputepw[degaussw]",
'degaussq': "inputepw[degaussq]",
'fsthick': "inputepw[fsthick]",
'ngaussw': "inputepw[ngaussw]",
'nsmear': "inputepw[nsmear]",
'delta_smear': "inputepw[delta_smear]",
'restart': "inputepw[restart]",
'restart_step': "inputepw[restart_step]",
'scissor': "inputepw[scissor]",
'lphase': "inputepw[lphase]",
'lpolar': "inputepw[lpolar]",
'efermi_read': "inputepw[efermi_read]",
'fermi_energy': "inputepw[fermi_energy]",
'lscreen': "inputepw[lscreen]",
'scr_typ': "inputepw[scr_typ]",
'fermi_diff': "inputepw[fermi_diff]",
'smear_rpa': "inputepw[smear_rpa]",
'lifc': "inputepw[lifc]",
'asr_typ': "inputepw[asr_typ]",
'wannierize': "inputepw[wannierize]",
'amass': {'$': ("inputepw[amass]", options.set_one_amass_line, None)}
},
'wannier90': {
'num_iter': "inputepw[num_iter]",
'dis_win_max': "inputepw[dis_win_max]",
'dis_win_min': "inputepw[dis_win_min]",
'dis_froz_min': "inputepw[dis_froz_min]",
'dis_froz_max': "inputepw[dis_frox_max]",
'proj': {'$': ("inputepw[proj]", options.set_one_proj_line, None)},
'bands_skipped': "inputepw[bands_skipped]",
'iprint': "inputepw[iprint]",
'wannier_plot': ["inputepw[wannier_plot]",
("inputepw[wdata]", options.set_wdata_lines, None)
],
'wannier_plot_supercell': "inputepw[wannier_plot_supercell]",
'wannier_plot_scale': "inputepw[wannier_plot_scale]",
'wannier_plot_radius': "inputepw[wannier_plot_radius]",
'wannier_plot_list': {'@segment': ("inputepw[wdata]",
options.set_wdata_lines, None)},
'wannier_plot_format': ('inputepw[wdata]',
options.set_wdata_lines, None),
'use_ws': ("inputepw[wdata]", options.set_wdata_lines, None),
'reduce_unk': "inputepw[reduce_unk]",
'scdm_proj': "inputepw[scdm_proj]",
'scdm_sigma': "inputepw[scdm_sigma]",
'auto_projections': "inputepw[auto_projections]",
'scdm_entanglement': "inputepw[scdm_entaglement]",
'scdm_mu': "inputepw[scdm_mu]",
}
}

def __init__(self, **kwargs):
super().__init__(*conversion_maps_builder(self.EPW_TEMPLATE_MAP),
input_namelists=['inputepw'],
input_cards=[])
Loading

0 comments on commit 39adc1d

Please sign in to comment.