diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index da3c451f4..28bfc4963 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -6,7 +6,7 @@ jobs:
docs:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-18.04
steps:
- uses: actions/checkout@v1
@@ -37,7 +37,7 @@ jobs:
pre-commit:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-18.04
timeout-minutes: 30
steps:
@@ -69,7 +69,7 @@ jobs:
tests:
- runs-on: ubuntu-latest
+ runs-on: ubuntu-18.04
timeout-minutes: 30
strategy:
@@ -120,3 +120,9 @@ jobs:
touch local_exe/inpgen && chmod +x local_exe/inpgen
touch local_exe/fleur && chmod +x local_exe/fleur
./run_all_cov.sh
+
+ - name: Upload report to Codecov
+ uses: codecov/codecov-action@v1
+ with:
+ file: ./tests/coverage.xml
+ fail_ci_if_error: False
diff --git a/.gitignore b/.gitignore
index f2abc28d4..6c5af7cf9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
# Created by https://www.gitignore.io/api/python,linux,macos
-
+#
+.aiida/
submit_test/
### Python ###
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 58e0f27ae..0f44c7d3e 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,19 @@
+## v1.1.3
+### release compatible with AiiDA-core 1.3.0
+- still support of Fleur MaXR4 version with inpgen
+- Does not support yet for Fleur MaXR5 and new inpgen
+- Set_kpoints was moved from fleurinp to fleurinpmodifier
+- Break_symmetry of a structure was refactored
+- Implemented feature in fleurinputCalculation to set significant figures
+- Implemented feature scf can now use default queues specified in code extras
+- First implementation of relax type None, which cases the relax workchain to skip the
+relaxation, becoming a usual scf wc, which might make it easier to switch relaxation on
+and off in other workchains.
+- Fleur parser parses now the total magnetic moment of the cell
+- Introduced common constants, for bohr and htr, increased precision
+- Command line interface (CLI) `aiida-fleur` with various functionalities exposed
+- For devs: Increased test coverage, codecov is now added to CI and linked to badge
+removed some older outdated code
## v1.1.2
### release compatible with AiiDA-core 1.3.0
diff --git a/README.md b/README.md
index 76f80fb5e..a445d85c1 100644
--- a/README.md
+++ b/README.md
@@ -3,10 +3,10 @@
[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
[![GitHub release](https://img.shields.io/github/release/JuDFTteam/aiida-fleur.svg)](https://github.com/JuDFTteam/aiida-fleur/releases)
[![PyPI version](https://badge.fury.io/py/aiida-fleur.svg)](https://badge.fury.io/py/aiida-fleur)
-[![Build develop](https://travis-ci.org/JuDFTteam/aiida-fleur.svg?branch=master)](https://travis-ci.org/JuDFTteam/aiida-fleur)
-[![Coveralls github branch](https://github.com/JuDFTteam/aiida-fleur/blob/develop/aiida_fleur/tests/coverage.svg)](https://github.com/JuDFTteam/aiida-fleur/tree/develop)
-[![Code quality pylint](https://github.com/JuDFTteam/aiida-fleur/blob/develop/aiida_fleur/tests/pylint.svg)](https://github.com/JuDFTteam/aiida-fleur/tree/develop)
+[![PyPI pyversions](https://img.shields.io/pypi/pyversions/aiida-fleur.svg)](https://pypi.python.org/pypi/aiida-fleur)
+[![Build status](https://github.com/JuDFTteam/aiida-fleur/workflows/aiida-fleur/badge.svg?branch=develop&event=push)](https://github.com/JuDFTteam/aiida-fleur/actions)
[![Documentation Status](https://readthedocs.org/projects/aiida-fleur/badge/?version=develop)](https://aiida-fleur.readthedocs.io/en/develop/?badge=develop)
+[![codecov](https://codecov.io/gh/JuDFTteam/aiida-fleur/branch/develop/graph/badge.svg)](https://codecov.io/gh/JuDFTteam/aiida-fleur)
This software contains a plugin that enables the usage of the all-electron
@@ -14,6 +14,12 @@ DFT [FLEUR code](http://www.flapw.de) with the [AiiDA framework](http://www.aiid
Developed at [Forschungszentrum Jülich GmbH](http://www.fz-juelich.de/pgi/pgi-1/DE/Home/home_node.html)
+## Compatibility matrix
+
+| FLEUR Plugin | AiiDA CORE | Python | FLEUR |
+|-|-|-|-|
+| `v1.0.0 < v2.0.0` | | [![PyPI pyversions](https://img.shields.io/pypi/pyversions/aiida-fleur.svg)](https://pypi.org/project/aiida-fleur.svg) | MaXR1 < MaXR5 (v0.29)|
+| `< v0.6.3` | | [![PyPI pyversions](https://img.shields.io/pypi/pyversions/aiida-fleur/0.6.svg)](https://pypi.python.org/pypi/aiida-fleur/0.6.3/) | MaXR1 < MaXR3 (v0.28)|
### Documentation
@@ -37,7 +43,7 @@ In Extreme Data Workshop 2018 Proceedings, 2019, vol 40, p 43-48
### Comments/Disclaimer:
-The plug-in and the workflows will only work with a Fleur version using xml files as I/O.
+The plug-in and the workflows will only work with a Fleur version using xml files as I/O, i.e >v0.27.
### Contents
@@ -94,6 +100,49 @@ read_cif.py | This can be used as stand-alone to create StructureData nodes from
Utility and tools, which are independend of AiiDA are moved to the [masci-tools](https://github.com/JuDFTteam/masci-tools) (material science tools) repository,
which is a dependency of aiida-fleur.
+
+### Command line interface (CLI)
+
+Besides the python API, aiida-fleur comes with a builtin CLI: `aiida-fleur`.
+This interface is built using the click library and supports tab-completion.
+
+To enable tab-completion, add the following to your shell loading script, e.g. the .bashrc or virtual environment activate script:
+
+ eval "$(_AIIDA_FLEUR_COMPLETE=source aiida-fleur)"
+
+the main subcommands include:
+
+ data: Commands to create and inspect data nodes
+ fleurinp Commands to handle `FleurinpData` nodes.
+ parameter Commands to create and inspect `Dict` nodes containing FLAPW parameters
+ structure Commands to create and inspect `StructureData` nodes.
+ launch: Commands to launch workflows and calcjobs of aiida-fleur
+
+ banddos Launch a banddos workchain
+ corehole Launch a corehole workchain
+ create_magnetic Launch a create_magnetic workchain
+ dmi Launch a dmi workchain
+ eos Launch a eos workchain
+ fleur Launch a base_fleur workchain.
+ init_cls Launch an init_cls workchain
+ inpgen Launch an inpgen calcjob on given input If no code is...
+ mae Launch a mae workchain
+ relax Launch a base relax workchain # TODO final scf input
+ scf Launch a scf workchain
+ ssdisp Launch a ssdisp workchain
+
+ plot: Invoke the plot_fleur command on given nodes
+
+ workflow: Commands to inspect aiida-fleur workchains and prepare inputs
+
+for example to launch an scf workchain on a given structure execute:
+
+ $ aiida-fleur launch scf -i -f -S
+
+the command can also process structures in any format `ase` can handle, this includes `Cif`, `xsf` and `poscar` files. In such a case simply parse the path to the file:
+
+ $ aiida-fleur launch scf -i -f -S ./structure/Cu.cif
+
## Installation Instructions
From the aiida-fleur folder (after downloading the code, recommended) use:
@@ -154,7 +203,7 @@ Mainly AiiDA:
Easy plotting and other useful routines that do not depend on aiida_core are part of
the [masci-tools](https://github.com/JuDFTteam/masci-tools) (material science tools) repository.
-For easy ploting we recommend using 'plot_methods' from masci-tools, which are also deployed by the 'plot_fleur()' function.
+For easy plotting we recommend using 'plot_methods' from masci-tools, which are also deployed by the 'plot_fleur()' function.
## Further Information
diff --git a/aiida_fleur/__init__.py b/aiida_fleur/__init__.py
index 521641094..41430d285 100644
--- a/aiida_fleur/__init__.py
+++ b/aiida_fleur/__init__.py
@@ -12,4 +12,4 @@
'''
AiiDA-FLEUR
'''
-__version__ = '1.1.2'
+__version__ = '1.1.3'
diff --git a/aiida_fleur/calculation/fleur.py b/aiida_fleur/calculation/fleur.py
index 1de9a4d76..344407326 100644
--- a/aiida_fleur/calculation/fleur.py
+++ b/aiida_fleur/calculation/fleur.py
@@ -193,7 +193,7 @@ class FleurCalculation(CalcJob):
@classmethod
def define(cls, spec):
- super(FleurCalculation, cls).define(spec)
+ super().define(spec)
# spec.input('metadata.options.input_filename', valid_type=six.string_types,
# default=cls._INPXML_FILE_NAME)
diff --git a/aiida_fleur/calculation/fleurinputgen.py b/aiida_fleur/calculation/fleurinputgen.py
index 4fbb5758d..6d1a123c2 100644
--- a/aiida_fleur/calculation/fleurinputgen.py
+++ b/aiida_fleur/calculation/fleurinputgen.py
@@ -28,7 +28,7 @@
from aiida_fleur.data.fleurinp import FleurinpData
from aiida_fleur.tools.StructureData_util import abs_to_rel_f, abs_to_rel
from aiida_fleur.tools.xml_util import convert_to_fortran_bool, convert_to_fortran_string
-from aiida_fleur.common.constants import bohr_a
+from aiida_fleur.common.constants import BOHR_A
class FleurinputgenCalculation(CalcJob):
@@ -37,7 +37,7 @@ class FleurinputgenCalculation(CalcJob):
For more information about produced files and the FLEUR-code family, go to http://www.flapw.de/.
"""
- __version__ = '1.2.1'
+ __version__ = '1.2.2'
# Default input and output files
_INPUT_FILE = 'aiida.in' # will be shown with inputcat
@@ -51,7 +51,10 @@ class FleurinputgenCalculation(CalcJob):
_ERROR_FILE_NAME = 'out.error'
_STRUCT_FILE_NAME = 'struct.xsf'
- _settings_keys = ['additional_retrieve_list', 'remove_from_retrieve_list', 'cmdline']
+ _settings_keys = [
+ 'additional_retrieve_list', 'remove_from_retrieve_list', 'cmdline', 'significant_figures_cell',
+ 'significant_figures_positions'
+ ]
# TODO switch all these to init_internal_params?
_OUTPUT_SUBFOLDER = './fleur_inp_out/'
_PREFIX = 'aiida'
@@ -97,7 +100,7 @@ class FleurinputgenCalculation(CalcJob):
@classmethod
def define(cls, spec):
- super(FleurinputgenCalculation, cls).define(spec)
+ super().define(spec)
spec.input('metadata.options.input_filename', valid_type=six.string_types, default=cls._INPUT_FILE)
spec.input('metadata.options.output_filename', valid_type=six.string_types, default=cls._INPXML_FILE_NAME)
@@ -136,7 +139,7 @@ def define(cls, spec):
'ERROR_FLEURINPDATA_INPUT_NOT_VALID',
message=('During parsing: FleurinpData could not be initialized, see log. '
'Maybe no Schemafile was found or the Fleurinput is not valid.'))
- spec.exit_code(309, 'ERROR_FLEURINPDATE_NOT_VALID', message='During parsing: FleurinpData failed validation.')
+ spec.exit_code(309, 'ERROR_FLEURINPDATA_NOT_VALID', message='During parsing: FleurinpData failed validation.')
def prepare_for_submission(self, folder):
"""
@@ -170,7 +173,7 @@ def prepare_for_submission(self, folder):
# but we have to convert from Angstrom to a.u (bohr radii)
scaling_factors = [1.0, 1.0, 1.0]
scaling_lat = 1. # /bohr_to_ang = 0.52917720859
- scaling_pos = 1. / bohr_a # Angstrom to atomic
+ scaling_pos = 1. / BOHR_A # Angstrom to atomic
own_lattice = False # not self._use_aiida_structure
##########################################
@@ -258,7 +261,8 @@ def prepare_for_submission(self, folder):
if self._use_aiida_structure:
input_params.pop('lattice', {})
own_lattice = False
-
+ #TODO check if input parameter dict is consistent to given structure.
+ # if not issue warnings.
# TODO allow only usual kpt meshes and use therefore Aiida kpointData
# if self._use_kpoints:
# try:
@@ -301,14 +305,18 @@ def prepare_for_submission(self, folder):
scaling_factor_card = ''
cell_parameters_card = ''
-
+ # We allow to set the significant figures format, because sometimes
+ # inpgen has numerical problems which are not there with less precise formatting
+ sf_c = str(settings_dict.get('significant_figures_cell', 9))
+ sf_p = str(settings_dict.get('significant_figure_positions', 10))
if not own_lattice:
cell = structure.cell
for vector in cell:
scaled = [a * scaling_pos for a in vector] # scaling_pos=1./bohr_to_ang
- cell_parameters_card += ('{0:18.9f} {1:18.9f} {2:18.9f}' '\n'.format(scaled[0], scaled[1], scaled[2]))
- scaling_factor_card += ('{0:18.9f} {1:18.9f} {2:18.9f}'
- '\n'.format(scaling_factors[0], scaling_factors[1], scaling_factors[2]))
+ reg_string = '{0:18.' + sf_c + 'f} {1:18.' + sf_c + 'f} {2:18.' + sf_c + 'f}\n'
+ cell_parameters_card += (reg_string.format(scaled[0], scaled[1], scaled[2]))
+ reg_string = '{0:18.' + sf_c + 'f} {1:18.' + sf_c + 'f} {2:18.' + sf_c + 'f}\n'
+ scaling_factor_card += (reg_string.format(scaling_factors[0], scaling_factors[1], scaling_factors[2]))
#### ATOMIC_POSITIONS ####
@@ -348,24 +356,27 @@ def prepare_for_submission(self, folder):
vector_rel = abs_to_rel_f(pos, cell, structure.pbc)
vector_rel[2] = vector_rel[2] * scaling_pos
- if site_symbol != kind_name: # This is an important fact, if user renames it becomes a new specie!
+ if site_symbol != kind_name: # This is an important fact, if user renames it becomes a new atomtype or species!
try:
+ # Kind names can be more then numbers now, this might need to be reworked
head = kind_name.rstrip('0123456789')
kind_namet = int(kind_name[len(head):])
- if int(kind_name[len(head)]) > 4:
- raise InputValidationError('New specie name/label should start with a digit smaller than 4')
+ #if int(kind_name[len(head)]) > 4:
+ # raise InputValidationError('New specie name/label should start with a digit smaller than 4')
except ValueError:
- pass
+ self.report(
+ 'Warning: Kind name {} will be ignored by the FleurinputgenCalculation and not set a charge number.'
+ .format(kind_name))
else:
atomic_number_name = '{}.{}'.format(atomic_number, kind_namet)
# append a label to the detached atom
- atomic_positions_card_listtmp.append(' {0:7} {1:18.10f} {2:18.10f} {3:18.10f} {4}'
- '\n'.format(atomic_number_name, vector_rel[0], vector_rel[1],
- vector_rel[2], kind_namet))
+ reg_string = ' {0:7} {1:18.' + sf_p + 'f} {2:18.' + sf_p + 'f} {3:18.' + sf_p + 'f} {4}\n'
+ atomic_positions_card_listtmp.append(
+ reg_string.format(atomic_number_name, vector_rel[0], vector_rel[1], vector_rel[2], kind_namet))
else:
- atomic_positions_card_listtmp.append(' {0:7} {1:18.10f} {2:18.10f} {3:18.10f}'
- '\n'.format(atomic_number_name, vector_rel[0], vector_rel[1],
- vector_rel[2]))
+ reg_string = ' {0:7} {1:18.' + sf_p + 'f} {2:18.' + sf_p + 'f} {3:18.' + sf_p + 'f}\n'
+ atomic_positions_card_listtmp.append(
+ reg_string.format(atomic_number_name, vector_rel[0], vector_rel[1], vector_rel[2]))
# TODO check format
# we write it later, since we do not know what natoms is before the loop...
atomic_positions_card_list.append(' {0:3}\n'.format(natoms))
@@ -557,8 +568,8 @@ def get_input_data_text(key, val, value_only, mapping=None):
for elemk, itemval in six.iteritems(val):
try:
idx = mapping[elemk]
- except KeyError:
- raise ValueError("Unable to find the key '{}' in the mapping " 'dictionary'.format(elemk))
+ except KeyError as exc:
+ raise ValueError("Unable to find the key '{}' in the mapping " 'dictionary'.format(elemk)) from exc
list_of_strings.append((idx, ' {0}({2})={1} '.format(key, conv_to_fortran(itemval), idx)))
# changed {0}({2}) = {1}\n".format
diff --git a/aiida_fleur/cmdline/__init__.py b/aiida_fleur/cmdline/__init__.py
old mode 100644
new mode 100755
index 6e91f601d..05ed9c8e8
--- a/aiida_fleur/cmdline/__init__.py
+++ b/aiida_fleur/cmdline/__init__.py
@@ -10,5 +10,36 @@
# http://aiida-fleur.readthedocs.io/en/develop/ #
###############################################################################
'''
-AiiDA-FLEUR
+Module for the command line interface of AiiDA-FLEUR
'''
+import click
+import click_completion
+
+from aiida.cmdline.params import options, types
+from .launch import cmd_launch
+from .data import cmd_data
+from .workflows import cmd_workflow
+from .visualization import cmd_plot
+
+# Activate the completion of parameter types provided by the click_completion package
+# for bash: eval "$(_AIIDA_FLEUR_COMPLETE=source aiida-fleur)"
+click_completion.init()
+
+# Instead of using entrypoints and directly injecting verdi commands into aiida-core
+# we created our own separete CLI because verdi will prob change and become
+# less material science specific
+
+
+@click.group('aiida-fleur', context_settings={'help_option_names': ['-h', '--help']})
+@options.PROFILE(type=types.ProfileParamType(load_profile=True))
+def cmd_root(profile): # pylint: disable=unused-argument
+ """CLI for the `aiida-fleur` plugin."""
+
+
+# To avoid circular imports all commands are not yet connected to the root
+# but they have to be here because of bash completion
+
+cmd_root.add_command(cmd_launch)
+cmd_root.add_command(cmd_data)
+cmd_root.add_command(cmd_workflow)
+cmd_root.add_command(cmd_plot)
diff --git a/aiida_fleur/cmdline/commands/fleurinpdata.py b/aiida_fleur/cmdline/commands/fleurinpdata.py
deleted file mode 100644
index 4ac092fb0..000000000
--- a/aiida_fleur/cmdline/commands/fleurinpdata.py
+++ /dev/null
@@ -1,76 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-"""
-Contains verdi commands for fleurinpdata
-"""
-from __future__ import absolute_import
-import click
-
-
-# this will get replaced by data_plug.group
-#@data_plug.group('fleur.fleurinp')
-@click.group()
-def fleurinp():
- pass
-
-
-@fleurinp.command()
-def list_fleurinp():
- """
- list all Fleurinp data in the database and displays some information
- """
- click.echo('verdi data fleurinp list')
- #do a query and list all reuse AiiDA code
-
-
-@fleurinp.command()
-def show():
- """
- Shows some basic information about the fleurinp datastructure and dumbs the
- inp.xml
- """
- click.echo('verdi data fleurinp list')
-
-
-@fleurinp.command()
-def open_inp():
- """
- opens the inp.xml in some editor, readonly.
- inp.xml
- """
- click.echo('verdi data fleurinp list')
-
-
-# this is a maybe
-@fleurinp.command()
-def get_structure():
- """
- Prints some basic information about the structure data and return a structure uuid/pk
- """
- click.echo('verdi data fleurinp list')
-
-
-@fleurinp.command()
-def get_kpoints():
- """
- Prints some basic information about the kpoints data and returns a kpoints uuid/pk
- """
- click.echo('verdi data fleurinp kpoints')
-
-
-@fleurinp.command()
-def get_parameters():
- """
- Prints some basic information about the parameter data and returns a
- parameter data uuid/pk
- """
- click.echo('verdi data fleurinp parameter')
diff --git a/aiida_fleur/cmdline/commands/scf_wc.py b/aiida_fleur/cmdline/data/__init__.py
old mode 100644
new mode 100755
similarity index 56%
rename from aiida_fleur/cmdline/commands/scf_wc.py
rename to aiida_fleur/cmdline/data/__init__.py
index e7d76c829..6f44a8666
--- a/aiida_fleur/cmdline/commands/scf_wc.py
+++ b/aiida_fleur/cmdline/data/__init__.py
@@ -9,40 +9,22 @@
# For further information please visit http://www.flapw.de or #
# http://aiida-fleur.readthedocs.io/en/develop/ #
###############################################################################
+# pylint: disable=cyclic-import
+# ,reimported,unused-import,wrong-import-position
"""
-contains verdi commands for the scf workchain
-in general these should become options of verdi aiida-fleur workchains
+Module with CLI commands for various data types.
"""
-
-from __future__ import absolute_import
import click
-@click.group()
-def scf_wc():
- pass
-
-
-@scf_wc.command()
-def res_scf():
- """
- Prints the result node to screen
- """
- click.echo('verdi aiida-fleur scf res')
-
+@click.group('data')
+def cmd_data():
+ """Commands to create and inspect data nodes."""
-@scf_wc.command()
-def show_scf():
- """
- plots the results of a
- """
- click.echo('verdi aiida-fleur scf show')
+#cmd_root.add_command(cmd_data)
-@scf_wc.command()
-def list_scf():
- """
- similar to the verdi work list command, but this displays also some
- specific information about the scfs
- """
- click.echo('verdi aiida-fleur scf list')
+# Import the sub commands to register them with the CLI
+from .structure import cmd_structure
+from .parameters import cmd_parameter
+from .fleurinp import cmd_fleurinp
diff --git a/aiida_fleur/cmdline/data/fleurinp.py b/aiida_fleur/cmdline/data/fleurinp.py
new file mode 100755
index 000000000..23ae0648d
--- /dev/null
+++ b/aiida_fleur/cmdline/data/fleurinp.py
@@ -0,0 +1,182 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+"""
+Contains verdi commands for fleurinpdata
+"""
+from __future__ import absolute_import
+import click
+from aiida.cmdline.commands.cmd_data.cmd_list import query, list_options
+from aiida.cmdline.params import arguments, options, types
+from aiida.cmdline.utils import decorators, echo
+from aiida.cmdline.params.types import DataParamType
+from aiida.plugins import DataFactory
+#from aiida_fleur.data.fleurinp import FleurinpData
+from . import cmd_data
+FleurinpData = DataFactory('fleur.fleurinp')
+
+
+@click.group('fleurinp')
+def cmd_fleurinp():
+ """Commands to handle `FleurinpData` nodes."""
+
+
+cmd_data.add_command(cmd_fleurinp)
+
+
+@cmd_fleurinp.command('list')
+@list_options # usual aiida list options
+@click.option('--uuid/--no-uuid', default=False, show_default=True, help='Display uuid of nodes.')
+@click.option('--ctime/--no-ctime', default=False, show_default=True, help='Display ctime of nodes.')
+@click.option('--extras/--no-extras', default=True, show_default=True, help='Display extras of nodes.')
+@click.option('--strucinfo/--no-strucinfo',
+ default=False,
+ show_default=True,
+ help='Perpare additional information on the crystal structure to show. This slows down the query.')
+@decorators.with_dbenv()
+def list_fleurinp(raw, past_days, groups, all_users, strucinfo, uuid, ctime, extras):
+ """
+ List stored FleurinpData in the database with additional information
+ """
+ # do a query and list all reuse AiiDA code
+ from tabulate import tabulate
+ list_project_headers = ['Id', 'Label', 'Description', 'Files'] # these we always get
+ # 'UUID', 'Ctime',
+ columns_dict = {
+ 'ID': 'id',
+ 'Id': 'id',
+ 'UUID': 'uuid',
+ 'Ctime': 'ctime',
+ 'Label': 'label',
+ 'Description': 'description',
+ 'Files': 'attributes.files',
+ 'Extras': 'attributes.extras'
+ }
+
+ if uuid:
+ list_project_headers.append('UUID')
+ if ctime:
+ list_project_headers.append('Ctime')
+ if extras:
+ list_project_headers.append('Extras')
+
+ project = [columns_dict[k] for k in list_project_headers]
+ group_pks = None
+ if groups is not None:
+ group_pks = [g.pk for g in groups]
+
+ data_fleurinp = query(FleurinpData, project, past_days, group_pks, all_users)
+ if strucinfo: # second query
+ # we get the whole node to get some extra information
+ project2 = '*'
+ fleurinps = query(FleurinpData, project2, past_days, group_pks, all_users)
+ list_project_headers.append('Formula')
+ counter = 0
+ fleurinp_list_data = list()
+
+ # , 'Formula', 'Symmetry'
+ # It is fastest for list commands to only display content from a query
+ if not raw:
+ fleurinp_list_data.append(list_project_headers)
+ for j, entry in enumerate(data_fleurinp):
+ #print(entry)
+ for i, value in enumerate(entry):
+ if isinstance(value, list):
+ new_entry = list()
+ for elm in value:
+ if elm is None:
+ new_entry.append('')
+ else:
+ new_entry.append(elm)
+ entry[i] = ','.join(new_entry)
+ if strucinfo:
+ structure = fleurinps[j][0].get_structuredata_ncf()
+ formula = structure.get_formula()
+ entry.append(formula)
+ for i in range(len(entry), len(list_project_headers)):
+ entry.append(None)
+ counter += 1
+ fleurinp_list_data.extend(data_fleurinp)
+ if raw:
+ echo.echo(tabulate(fleurinp_list_data, tablefmt='plain'))
+ else:
+ echo.echo(tabulate(fleurinp_list_data, headers='firstrow'))
+ echo.echo('\nTotal results: {}\n'.format(counter))
+
+
+@cmd_fleurinp.command('cat')
+@arguments.NODE('node', type=DataParamType(sub_classes=('aiida.data:fleur.fleurinp',)))
+@click.option('-f',
+ '--filename',
+ 'filename',
+ default='inp.xml',
+ show_default=True,
+ help='Disply the file content of the given filename.')
+def cat_file(node, filename):
+ """
+ Dumb the content of a file contained in given fleurinpdata, per default dump
+ inp.xml
+ """
+ echo.echo(node.get_content(filename=filename))
+
+
+'''
+@cmd_fleurinp.command('info')
+def info():
+ """
+ Shows some basic information about the fleurinp datastructure and dumbs the
+ inp.xml
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+
+
+@cmd_fleurinp.command('show')
+def cmd_show():
+ """
+ Shows the content of a certain file
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+
+
+@cmd_fleurinp.command('open')
+def open_inp():
+ """
+ opens the inp.xml in some editor, readonly.
+ inp.xml this way looking at xml might be more convenient.
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+
+
+# this is a maybe
+@cmd_fleurinp.command()
+def get_structure():
+ """
+ Prints some basic information about the structure data and return a structure uuid/pk
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+
+
+@cmd_fleurinp.command()
+def get_kpoints():
+ """
+ Prints some basic information about the kpoints data and returns a kpoints uuid/pk
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+
+
+@cmd_fleurinp.command()
+def get_parameters():
+ """
+ Prints some basic information about the parameter data and returns a
+ parameter data uuid/pk
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+'''
diff --git a/aiida_fleur/cmdline/data/parameters.py b/aiida_fleur/cmdline/data/parameters.py
new file mode 100644
index 000000000..cffbb0d74
--- /dev/null
+++ b/aiida_fleur/cmdline/data/parameters.py
@@ -0,0 +1,66 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+# pylint: disable=cyclic-import
+"""Command line utilities to create and inspect `Dict` nodes with FLAPW parameters."""
+import click
+
+from aiida.cmdline.params import options
+from aiida.cmdline.utils import decorators, echo
+
+from . import cmd_data
+
+
+@cmd_data.group('parameter')
+def cmd_parameter():
+ """Commands to create and inspect `Dict` nodes containing FLAPW parameters ('calc_parameters')."""
+
+
+@cmd_parameter.command('import')
+@click.argument('filename', type=click.Path(exists=True))
+@click.option('--fleurinp/--no-fleurinp',
+ default=False,
+ show_default=True,
+ help='Store also the fleurinp and the extractor calcfunction in the db.')
+@click.option('--show/--no-show', default=True, show_default=True, help='Print the contents from the extracted dict.')
+@options.DRY_RUN()
+@decorators.with_dbenv()
+def cmd_param_import(filename, dry_run, fleurinp, show):
+ """
+ Extract FLAPW parameters from a Fleur input file and store as Dict in the db.
+
+ FILENAME is the name/path of the inp.xml file to use.
+ """
+ from aiida_fleur.data.fleurinp import FleurinpData
+
+ if not filename.endswith('.xml'):
+ echo.echo_critical('Error: Currently, we can only extract information from an inp.xml file.')
+ fleurinpd = FleurinpData(files=[filename])
+ if not fleurinp or dry_run:
+ parameters = fleurinpd.get_parameterdata_ncf()
+ else:
+ parameters = fleurinpd.get_parameterdata(fleurinpd)
+
+ if dry_run:
+ echo.echo_success('parsed FLAPW parameters')
+ else:
+ parameters.store()
+ echo.echo_success(f'parsed and stored FLAPW parameters<{parameters.pk}> <{parameters.uuid}>')
+
+ if show:
+ echo.echo_dictionary(parameters.get_dict())
+
+
+# further ideas:
+# query for certain FLAPW parameter nodes.
+# Example show me all for Si
+# query for options nodes
+# command to split and merge parameters nodes together based on elements.
diff --git a/aiida_fleur/cmdline/data/structure.py b/aiida_fleur/cmdline/data/structure.py
new file mode 100755
index 000000000..bded4de20
--- /dev/null
+++ b/aiida_fleur/cmdline/data/structure.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+"""Command line utilities to create and inspect `StructureData` nodes."""
+import click
+from aiida.cmdline.params import options
+from aiida.cmdline.utils import decorators, echo
+
+from . import cmd_data
+
+
+@click.group('structure')
+def cmd_structure():
+ """Commands to create and inspect `StructureData` nodes."""
+
+
+cmd_data.add_command(cmd_structure)
+# import filename
+# import -N pk_fleurinp
+
+
+@cmd_structure.command('import')
+@click.argument('filename', type=click.Path(exists=True))
+@click.option('--fleurinp/--no-fleurinp',
+ default=False,
+ show_default=True,
+ help='Store also the fleurinp and the extractor calcfunction in the db.')
+@options.DRY_RUN()
+@decorators.with_dbenv()
+def cmd_import(filename, dry_run, fleurinp):
+ """
+ Import a `StructureData` from a Fleur input file.
+
+ FILENAME is the name/path of the inp.xml file to use.
+
+ If you want to import a structure from any file type you can use
+ 'verdi data structure import -ase ' instead.
+ """
+ from aiida_fleur.data.fleurinp import FleurinpData
+
+ if not filename.endswith('.xml'):
+ echo.echo_critical('Error: Currently, only StructureData from a inp.xml file can be extracted.')
+ fleurinpd = FleurinpData(files=[filename])
+ if not fleurinp or dry_run:
+ structure = fleurinpd.get_structuredata_ncf()
+ else:
+ structure = fleurinpd.get_structuredata()
+ formula = structure.get_formula()
+
+ if dry_run:
+ echo.echo_success(f'parsed structure with formula {formula}')
+ else:
+ structure.store()
+ echo.echo_success(
+ f'parsed and stored StructureData<{structure.pk}> with formula {formula}, also stored FleurinpData<{fleurinpd.pk}>'
+ )
diff --git a/aiida_fleur/cmdline/launch/__init__.py b/aiida_fleur/cmdline/launch/__init__.py
new file mode 100644
index 000000000..c8e32e054
--- /dev/null
+++ b/aiida_fleur/cmdline/launch/__init__.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module with CLI commands for calcjob types of aiida-fleur.
+'''
+import click
+from .launch import launch_inpgen
+from .launch import launch_fleur
+from .launch import launch_scf
+from .launch import launch_banddos
+from .launch import launch_relax
+from .launch import launch_eos
+from .launch import launch_corehole
+from .launch import launch_init_cls
+from .launch import launch_mae
+from .launch import launch_create_magnetic
+from .launch import launch_dmi
+from .launch import launch_ssdisp
+
+
+@click.group('launch')
+def cmd_launch():
+ """Commands to launch workflows and calcjobs of aiida-fleur."""
+
+
+# we do it like this and not in short from to avoid cyclic imports
+# and get the full bash completion working
+cmd_launch.add_command(launch_inpgen)
+cmd_launch.add_command(launch_fleur)
+cmd_launch.add_command(launch_scf)
+cmd_launch.add_command(launch_banddos)
+cmd_launch.add_command(launch_relax)
+cmd_launch.add_command(launch_eos)
+cmd_launch.add_command(launch_corehole)
+cmd_launch.add_command(launch_init_cls)
+cmd_launch.add_command(launch_mae)
+cmd_launch.add_command(launch_create_magnetic)
+cmd_launch.add_command(launch_dmi)
+cmd_launch.add_command(launch_ssdisp)
diff --git a/aiida_fleur/cmdline/launch/launch.py b/aiida_fleur/cmdline/launch/launch.py
new file mode 100755
index 000000000..8e0720729
--- /dev/null
+++ b/aiida_fleur/cmdline/launch/launch.py
@@ -0,0 +1,480 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module with CLI commands to launch for calcjob and workflows of aiida-fleur.
+'''
+# TODO: these launch commands should be put in separate files, if this one becomes to large..
+
+import click
+from ..util import options
+from ..util.utils import launch_process
+from ..util import defaults
+from aiida_fleur.tools.dict_util import clean_nones
+from aiida.orm import Code, load_node, Dict
+from aiida.plugins import WorkflowFactory
+from aiida.plugins import CalculationFactory
+
+
+@click.command('inpgen')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.SETTINGS()
+@options.DAEMON()
+def launch_inpgen(structure, inpgen, calc_parameters, settings, daemon):
+ """
+ Launch an inpgen calcjob on given input
+
+ If no code is given it queries the DB for inpgen codes and uses the one with
+ the newest creation time.
+
+ Either structure or anysource_structure can be specified.
+ Default structure is Si bulk.
+ """
+
+ process_class = CalculationFactory('fleur.inpgen')
+ inputs = {
+ 'code': inpgen,
+ 'structure': structure,
+ 'parameters': calc_parameters,
+ 'settings': settings,
+ 'metadata': {
+ 'options': {
+ 'withmpi': False,
+ 'max_wallclock_seconds': 6000,
+ 'resources': {
+ 'num_machines': 1,
+ 'num_mpiprocs_per_machine': 1,
+ }
+ }
+ }
+ }
+ inputs = clean_nones(inputs)
+ builder = process_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('fleur')
+@options.FLEURINP()
+@options.FLEUR()
+@options.REMOTE()
+@options.SETTINGS()
+@options.DAEMON()
+@options.MAX_NUM_MACHINES()
+@options.MAX_WALLCLOCK_SECONDS()
+@options.NUM_MPIPROCS_PER_MACHINE()
+@options.OPTION_NODE()
+@options.WITH_MPI()
+@click.option('--launch_base/--no-launch_base',
+ is_flag=True,
+ default=True,
+ show_default=True,
+ help=('Run the base_fleur workchain, which also handles errors instead '
+ 'of a single fleur calcjob.'))
+def launch_fleur(fleurinp, fleur, parent_folder, settings, daemon, max_num_machines, max_wallclock_seconds,
+ num_mpiprocs_per_machine, option_node, with_mpi, launch_base):
+ """
+ Launch a base_fleur workchain.
+ If launch_base is False launch a single fleur calcjob instead.
+
+ """
+
+ process_class = CalculationFactory('fleur.fleur')
+ workchain_class = WorkflowFactory('fleur.base')
+
+ inputs = {
+ 'code': fleur,
+ 'fleurinpdata': fleurinp,
+ 'parent_folder': parent_folder,
+ 'settings': settings,
+ 'metadata': {
+ 'options': {
+ 'withmpi': with_mpi,
+ 'max_wallclock_seconds': max_wallclock_seconds,
+ 'resources': {
+ 'num_machines': max_num_machines,
+ 'num_mpiprocs_per_machine': num_mpiprocs_per_machine,
+ }
+ }
+ }
+ }
+
+ if not launch_base:
+ inputs = clean_nones(inputs)
+ builder = process_class.get_builder()
+ builder.update(inputs)
+ else:
+ if option_node is None:
+ option_node = Dict(
+ dict={
+ 'withmpi': with_mpi,
+ 'max_wallclock_seconds': max_wallclock_seconds,
+ 'resources': {
+ 'num_machines': max_num_machines,
+ 'num_mpiprocs_per_machine': num_mpiprocs_per_machine
+ }
+ })
+
+ inputs_base = {
+ 'code': fleur,
+ 'fleurinpdata': fleurinp,
+ 'parent_folder': parent_folder,
+ 'settings': settings,
+ 'options': option_node
+ }
+ inputs_base = clean_nones(inputs_base)
+ builder = workchain_class.get_builder()
+ builder.update(**inputs_base)
+
+ launch_process(builder, daemon)
+
+
+@click.command('scf')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.SETTINGS()
+@options.FLEURINP()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.REMOTE()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_scf(structure, inpgen, calc_parameters, fleurinp, fleur, wf_parameters, parent_folder, daemon, settings,
+ option_node):
+ """
+ Launch a scf workchain
+ """
+ workchain_class = WorkflowFactory('fleur.scf')
+ inputs = {
+ 'inpgen': inpgen,
+ 'fleur': fleur,
+ 'structure': structure,
+ 'fleurinp': fleurinp,
+ 'wf_parameters': wf_parameters,
+ 'calc_parameters': calc_parameters,
+ 'remote_data': parent_folder,
+ 'settings': settings,
+ 'options': option_node
+ }
+
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('relax')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.SCF_PARAMETERS()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_relax(structure, inpgen, calc_parameters, fleur, wf_parameters, scf_parameters, daemon, settings,
+ option_node):
+ """
+ Launch a base relax workchain
+
+ # TODO final scf input
+ """
+ workchain_class = WorkflowFactory('fleur.base_relax')
+ inputs = {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'structure': structure,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': wf_parameters
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('eos')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.SCF_PARAMETERS()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_eos(structure, inpgen, calc_parameters, fleur, wf_parameters, scf_parameters, daemon, settings, option_node):
+ """
+ Launch a eos workchain
+ """
+ workchain_class = WorkflowFactory('fleur.eos')
+ inputs = {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': wf_parameters,
+ 'structure': structure
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('banddos')
+@options.FLEURINP()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.REMOTE()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_banddos(fleurinp, fleur, wf_parameters, parent_folder, daemon, settings, option_node):
+ """
+ Launch a banddos workchain
+ """
+ workchain_class = WorkflowFactory('fleur.banddos')
+ inputs = {
+ 'wf_parameters': wf_parameters,
+ 'fleur': fleur,
+ 'remote': parent_folder,
+ 'fleurinp': fleurinp,
+ 'options': option_node
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('init_cls')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEURINP()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_init_cls(structure, inpgen, calc_parameters, fleurinp, fleur, wf_parameters, daemon, settings, option_node):
+ """
+ Launch an init_cls workchain
+ """
+ workchain_class = WorkflowFactory('fleur.init_cls')
+ inputs = {
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur,
+ 'wf_parameters': wf_parameters,
+ 'structure': structure
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('corehole')
+@options.STRUCTURE_OR_FILE(default=defaults.get_si_bulk_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEURINP()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_corehole(structure, inpgen, calc_parameters, fleurinp, fleur, wf_parameters, daemon, settings, option_node):
+ """
+ Launch a corehole workchain
+ """
+ workchain_class = WorkflowFactory('fleur.corehole')
+ inputs = {
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur,
+ 'wf_parameters': wf_parameters,
+ 'structure': structure
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('mae')
+@options.STRUCTURE_OR_FILE(default=defaults.get_fept_film_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEURINP()
+@options.FLEUR()
+@options.WF_PARAMETERS()
+@options.SCF_PARAMETERS()
+@options.REMOTE()
+@options.DAEMON()
+@options.SETTINGS()
+@options.OPTION_NODE()
+def launch_mae(structure, inpgen, calc_parameters, fleurinp, fleur, wf_parameters, scf_parameters, parent_folder,
+ daemon, settings, option_node):
+ """
+ Launch a mae workchain
+ """
+ workchain_class = WorkflowFactory('fleur.mae')
+ inputs = {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'structure': structure,
+ 'calc_parameters': calc_parameters,
+ 'settings': settings,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': wf_parameters,
+ 'fleurinp': fleurinp,
+ 'remote': parent_folder,
+ 'fleur': fleur,
+ 'options': option_node
+ }
+
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('create_magnetic')
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEUR()
+@options.WF_PARAMETERS(required=True)
+@options.EOS_PARAMETERS()
+@options.SCF_PARAMETERS()
+@options.RELAX_PARAMETERS()
+@options.DAEMON()
+@options.OPTION_NODE()
+def launch_create_magnetic(inpgen, calc_parameters, fleur, wf_parameters, eos_parameters, scf_parameters,
+ relax_parameters, daemon, option_node):
+ """
+ Launch a create_magnetic workchain
+ """
+ workchain_class = WorkflowFactory('fleur.create_magnetic')
+ inputs = {
+ 'eos': {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': eos_parameters
+ },
+ 'relax': {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': relax_parameters,
+ 'label': 'relaxation',
+ },
+ 'wf_parameters': wf_parameters
+ }
+
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('ssdisp')
+@options.STRUCTURE_OR_FILE(default=defaults.get_fept_film_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEUR()
+@options.WF_PARAMETERS(required=True)
+@options.SCF_PARAMETERS()
+@options.DAEMON()
+@options.OPTION_NODE()
+def launch_ssdisp(structure, inpgen, calc_parameters, fleur, wf_parameters, scf_parameters, daemon, option_node):
+ """
+ Launch a ssdisp workchain
+ """
+ workchain_class = WorkflowFactory('fleur.ssdisp')
+ inputs = {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'structure': structure,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': wf_parameters,
+ 'fleur': fleur,
+ 'options': option_node
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
+
+
+@click.command('dmi')
+@options.STRUCTURE_OR_FILE(default=defaults.get_fept_film_structure, show_default=True)
+@options.INPGEN()
+@options.CALC_PARAMETERS()
+@options.FLEUR()
+@options.WF_PARAMETERS(required=True)
+@options.SCF_PARAMETERS()
+@options.DAEMON()
+@options.OPTION_NODE()
+def launch_dmi(structure, inpgen, calc_parameters, fleur, wf_parameters, scf_parameters, daemon, option_node):
+ """
+ Launch a dmi workchain
+ """
+ click.echo('Not implemented yet, sorry. Please implement me!')
+ workchain_class = WorkflowFactory('fleur.dmi')
+ inputs = {
+ 'scf': {
+ 'wf_parameters': scf_parameters,
+ 'structure': structure,
+ 'calc_parameters': calc_parameters,
+ 'options': option_node,
+ 'inpgen': inpgen,
+ 'fleur': fleur
+ },
+ 'wf_parameters': wf_parameters,
+ 'fleur': fleur,
+ 'options': option_node
+ }
+ inputs = clean_nones(inputs)
+ builder = workchain_class.get_builder()
+ builder.update(inputs)
+ launch_process(builder, daemon)
diff --git a/aiida_fleur/cmdline/commands/workchains.py b/aiida_fleur/cmdline/list/__init__.py
old mode 100644
new mode 100755
similarity index 51%
rename from aiida_fleur/cmdline/commands/workchains.py
rename to aiida_fleur/cmdline/list/__init__.py
index ca4905af8..318a115bb
--- a/aiida_fleur/cmdline/commands/workchains.py
+++ b/aiida_fleur/cmdline/list/__init__.py
@@ -9,40 +9,12 @@
# For further information please visit http://www.flapw.de or #
# http://aiida-fleur.readthedocs.io/en/develop/ #
###############################################################################
-"""
-contains verdi commands that are useful for fleur workchains
-"""
+'''
+Module with CLI commands for calcjob types of aiida-fleur.
+'''
+from .. import cmd_root
-from __future__ import absolute_import
-import click
-
-@click.group()
-def workchains():
- pass
-
-
-@workchains.command()
-def res_wc():
- """
- Prints the result node to screen
- """
- click.echo('verdi aiida-fleur workchains res pk/uuid/list')
-
-
-@workchains.command()
-def show_wc():
- """
- plots the results of a workchain
- """
- click.echo('verdi aiida-fleur workchains show pk/uuid/list')
-
-
-@workchains.command()
-def list_wc():
- """
- similar to the verdi work list command, but this displays also some
- specific information about the fleur workchains, can be filtered for
- certain workchains...
- """
- click.echo('verdi aiida-fleur workchians list -scf -A -p')
+@cmd_root.group('list')
+def cmd_calcjob():
+ """Command group to list calcjobs and workflows of aiida-fleur."""
diff --git a/aiida_fleur/cmdline/commands/__init__.py b/aiida_fleur/cmdline/util/__init__.py
old mode 100644
new mode 100755
similarity index 100%
rename from aiida_fleur/cmdline/commands/__init__.py
rename to aiida_fleur/cmdline/util/__init__.py
diff --git a/aiida_fleur/cmdline/util/defaults.py b/aiida_fleur/cmdline/util/defaults.py
new file mode 100644
index 000000000..8982068ed
--- /dev/null
+++ b/aiida_fleur/cmdline/util/defaults.py
@@ -0,0 +1,123 @@
+# -*- coding: utf-8 -*-
+"""
+Here we specify some defaults for cli commands
+"""
+
+# Structures
+
+
+def get_si_bulk_structure():
+ """Return a `StructureData` representing bulk silicon.
+
+ The database will first be queried for the existence of a bulk silicon crystal. If this is not the case, one is
+ created and stored. This function should be used as a default for CLI options that require a `StructureData` node.
+ This way new users can launch the command without having to construct or import a structure first. This is the
+ reason that we hardcode a bulk silicon crystal to be returned. More flexibility is not required for this purpose.
+
+ :return: a `StructureData` representing bulk silicon
+ """
+ from ase.spacegroup import crystal
+ from aiida.orm import QueryBuilder, StructureData
+
+ # Filters that will match any elemental Silicon structure with 2 or less sites in total
+ filters = {
+ 'attributes.sites': {
+ 'of_length': 2
+ },
+ 'attributes.kinds': {
+ 'of_length': 1
+ },
+ 'attributes.kinds.0.symbols.0': 'Si'
+ }
+
+ builder = QueryBuilder().append(StructureData, filters=filters)
+ results = builder.first()
+
+ if not results:
+ alat = 5.43
+ ase_structure = crystal(
+ 'Si',
+ [(0, 0, 0)],
+ spacegroup=227,
+ cellpar=[alat, alat, alat, 90, 90, 90],
+ primitive_cell=True,
+ )
+ structure = StructureData(ase=ase_structure)
+ structure.store()
+ else:
+ structure = results[0]
+
+ return structure.uuid
+
+
+def get_fept_film_structure():
+ """Return a `StructureData` representing FePt film.
+
+ The database will first be queried for the existence of a FePt film. If this is not the case, one is
+ created and stored. This function should be used as a default for CLI options that require a `StructureData` node.
+ This way new users can launch the command without having to construct or import a structure first. This is the
+ reason that we hardcode a FePt film to be returned. More flexibility is not required for this purpose.
+
+ :return: the uuid of `StructureData` representing a FePt film
+ """
+ from aiida.orm import StructureData, QueryBuilder
+
+ bohr_a_0 = 0.52917721092 # A
+ a = 7.497 * bohr_a_0
+ cell = [[0.7071068 * a, 0.0, 0.0], [0.0, 1.0 * a, 0.0], [0.0, 0.0, 0.7071068 * a]]
+ structure = StructureData(cell=cell)
+ structure.append_atom(position=(0.0, 0.0, -1.99285 * bohr_a_0), symbols='Fe', name='Fe123')
+ structure.append_atom(position=(0.5 * 0.7071068 * a, 0.5 * a, 0.0), symbols='Pt')
+ structure.append_atom(position=(0., 0., 2.65059 * bohr_a_0), symbols='Pt')
+ structure.pbc = (True, True, False)
+
+ builder = QueryBuilder().append(StructureData, filters={'extras._aiida_hash': structure._get_hash()})
+ results = builder.first()
+
+ if not results:
+ structure.store()
+ else:
+ structure = results[0]
+
+ return structure.uuid
+
+
+# Codes
+def get_inpgen():
+ """Return a `Code` node of the latest added inpgen executable in the database."""
+
+ return get_last_code('fleur.inpgen')
+
+
+def get_fleur():
+ """Return a `Code` node of the latest added inpgen executable in the database."""
+
+ return get_last_code('fleur.fleur')
+
+
+def get_last_code(entry_point_name):
+ """Return a `Code` node of the latest code executable of the given entry_point_name in the database.
+
+ The database will be queried for the existence of a inpgen node.
+ If this is not exists and NotExistent error is raised.
+
+
+ :param entry_point_name: string
+ :return: the uuid of a inpgen `Code` node
+ :raise: aiida.common.exceptions.NotExistent
+ """
+ from aiida.orm import QueryBuilder, Code
+ from aiida.common.exceptions import NotExistent
+
+ filters = {'attributes.input_plugin': {'==': entry_point_name}}
+
+ builder = QueryBuilder().append(Code, filters=filters)
+ builder.order_by({Code: {'ctime': 'asc'}})
+ results = builder.first()
+
+ if not results:
+ raise NotExistent(f'ERROR: Could not find any Code in the database with entry point: {entry_point_name}!')
+ else:
+ inpgen = results[0]
+
+ return inpgen.uuid
diff --git a/aiida_fleur/cmdline/util/options.py b/aiida_fleur/cmdline/util/options.py
new file mode 100755
index 000000000..a498a38cc
--- /dev/null
+++ b/aiida_fleur/cmdline/util/options.py
@@ -0,0 +1,152 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+"""
+Options commonly used throughout the aiida-fleur command line interface.
+To standardize at least of the options, they are kept as close as possible to
+aiida-core and aiida-quantumespresso
+"""
+import click
+from aiida.cmdline.params import types
+from aiida.cmdline.params.options import OverridableOption
+from .defaults import get_inpgen, get_fleur, get_si_bulk_structure
+from .types import StructureNodeOrFileParamType
+
+STRUCTURE_OR_FILE = OverridableOption(
+ '-s',
+ '--structure',
+ type=StructureNodeOrFileParamType(),
+ help='StructureData node, given by pk or uuid or file in any for mat which will be converted.')
+
+STRUCTURE = OverridableOption('-s',
+ '--structure',
+ type=types.DataParamType(sub_classes=('aiida.data:structure',)),
+ help='StructureData node, given by pk or uuid.')
+
+FULL_PROVENANCE = OverridableOption('-fp',
+ '--full-provenance',
+ is_flag=True,
+ default=False,
+ show_default=True,
+ help=('Store the full or reduced provenance. Example with the "-as" '
+ 'also the given file will be stored in the database together with a '
+ 'calcfunction extracting the structure.'))
+
+INPGEN = OverridableOption('-i',
+ '--inpgen',
+ type=types.CodeParamType(entry_point='fleur.inpgen'),
+ default=get_inpgen,
+ show_default=True,
+ help='A code node or label for an inpgen executable.')
+
+FLEUR = OverridableOption('-f',
+ '--fleur',
+ type=types.CodeParamType(entry_point='fleur.fleur'),
+ default=get_fleur,
+ show_default=True,
+ help='A code node or label for a fleur executable.')
+
+FLEURINP = OverridableOption('-inp',
+ '--fleurinp',
+ type=types.DataParamType(sub_classes=('aiida.data:fleur.fleurinp',)),
+ help='FleurinpData node for the fleur calculation.')
+
+CALC_PARAMETERS = OverridableOption(
+ '-calc_p',
+ '--calc-parameters',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict with calculation (FLAPW) parameters to build, which will be given to inpgen.')
+
+SETTINGS = OverridableOption('-set',
+ '--settings',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Settings node for the calcjob.')
+
+WF_PARAMETERS = OverridableOption('-wf',
+ '--wf-parameters',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict containing parameters given to the workchain.')
+
+SCF_PARAMETERS = OverridableOption('-scf',
+ '--scf-parameters',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict containing parameters given to the sub SCF workchains.')
+
+EOS_PARAMETERS = OverridableOption('-eos',
+ '--eos-parameters',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict containing wf parameters given to the sub EOS workchains.')
+
+RELAX_PARAMETERS = OverridableOption('-relax',
+ '--relax-parameters',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict containing wf parameters given to the sub relax workchains.')
+
+OPTION_NODE = OverridableOption('-opt',
+ '--option-node',
+ type=types.DataParamType(sub_classes=('aiida.data:dict',)),
+ help='Dict, an option node for the workchain.')
+
+MAX_NUM_MACHINES = OverridableOption('-N',
+ '--max-num-machines',
+ type=click.INT,
+ default=1,
+ show_default=True,
+ help='The maximum number of machines (nodes) to use for the calculations.')
+
+MAX_WALLCLOCK_SECONDS = OverridableOption('-W',
+ '--max-wallclock-seconds',
+ type=click.INT,
+ default=1800,
+ show_default=True,
+ help='The maximum wallclock time in seconds to set for the calculations.')
+
+NUM_MPIPROCS_PER_MACHINE = OverridableOption('-M',
+ '--num-mpiprocs-per-machine',
+ type=click.INT,
+ default=12,
+ show_default=True,
+ help='Run the simulation with so many num-mpi-procs-per-machine.')
+
+WITH_MPI = OverridableOption('-I',
+ '--with-mpi',
+ is_flag=True,
+ default=False,
+ show_default=True,
+ help='Run the calculations with MPI enabled.')
+
+REMOTE = OverridableOption('-P',
+ '--parent-folder',
+ 'parent_folder',
+ type=types.DataParamType(sub_classes=('aiida.data:remote',)),
+ show_default=True,
+ required=False,
+ help='The PK of a parent remote folder (for restarts).')
+
+DAEMON = OverridableOption('-d',
+ '--daemon',
+ is_flag=True,
+ default=False,
+ show_default=True,
+ help='Submit the process to the daemon instead of running it locally.')
+
+CLEAN_WORKDIR = OverridableOption(
+ '-x',
+ '--clean-workdir',
+ is_flag=True,
+ default=False,
+ show_default=True,
+ help='Clean the remote folder of all the launched calculations after completion of the workchain.')
+
+SHOW = OverridableOption('--show/--no-show',
+ default=True,
+ show_default=True,
+ help='Show the main output of the command.')
diff --git a/aiida_fleur/cmdline/util/types.py b/aiida_fleur/cmdline/util/types.py
new file mode 100644
index 000000000..a4eeff1f4
--- /dev/null
+++ b/aiida_fleur/cmdline/util/types.py
@@ -0,0 +1,70 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+This module contains click option types specific to aiida-fleur
+'''
+import click
+from aiida.cmdline.params import types
+from aiida.cmdline.utils import echo
+from aiida.common.exceptions import NotExistent
+from aiida.plugins import DataFactory
+from aiida.cmdline.utils.decorators import with_dbenv
+
+
+class StructureNodeOrFileParamType(click.ParamType):
+ """
+ The ParamType for identifying a structure by node or to extract it from a given file
+
+ Pro: It is convenient
+ Con: If users only use other formats to launch their workflows it will create many
+ more structures in the database.
+ """
+
+ name = 'StructureFile'
+
+ @with_dbenv()
+ def convert(self, value, param, ctx):
+ is_path = False
+ # Alternative one could check if int or uuid
+ # aiida allows also for shorten uuids
+ from aiida.orm import StructureData, QueryBuilder
+
+ try:
+ structure = types.DataParamType(sub_classes=('aiida.data:structure',)).convert(value, param, ctx)
+ except (NotExistent, click.exceptions.BadParameter) as er:
+ echo.echo(f'Tried to load node, could not fine one for {value}. '
+ 'I will further check if it is a filepath.')
+ is_path = True
+
+ if is_path:
+ # If it is a path to a file try to convert the structure
+ pathtype = click.Path(exists=True, dir_okay=False, resolve_path=True)
+ filename = pathtype.convert(value, param, ctx)
+ try:
+ import ase.io
+ except ImportError:
+ echo.echo_critical('You have not installed the package ase. \nYou can install it with: pip install ase')
+
+ try:
+ asecell = ase.io.read(filename)
+ structure = StructureData(ase=asecell)
+ except ValueError as err:
+ echo.echo_critical(str(err))
+ # do not store structure, since this option is for calculation and workflow
+ # input, which will store the structure anyway.
+
+ # do not store again if structure is already there.
+ duplicate = QueryBuilder().append(StructureData, filters={'extras._aiida_hash': structure._get_hash()}).first() # pylint: disable=protected-access
+
+ if duplicate:
+ return duplicate[0]
+ return structure
diff --git a/aiida_fleur/cmdline/util/utils.py b/aiida_fleur/cmdline/util/utils.py
new file mode 100644
index 000000000..4b64fe013
--- /dev/null
+++ b/aiida_fleur/cmdline/util/utils.py
@@ -0,0 +1,65 @@
+# -*- coding: utf-8 -*-
+"""
+Module with utitlies for the CLI.
+
+The echo_process_results and launch_process routines have been copied from
+aiida-common-workflows repository found under cli utils
+"""
+import click
+
+
+def echo_process_results(node):
+ """Display a formatted table of the outputs registered for the given process node.
+
+ :param node: the `ProcessNode` of a terminated process.
+ """
+ from aiida.common.links import LinkType
+
+ class_name = node.process_class.__name__
+ outputs = node.get_outgoing(link_type=(LinkType.CREATE, LinkType.RETURN)).all()
+
+ if node.is_finished and node.exit_message:
+ state = '{} [{}] `{}`'.format(node.process_state.value, node.exit_status, node.exit_message)
+ elif node.is_finished:
+ state = '{} [{}]'.format(node.process_state.value, node.exit_status)
+ else:
+ state = node.process_state.value
+
+ click.echo('{}<{}> terminated with state: {}'.format(class_name, node.pk, state))
+
+ if not outputs:
+ click.echo('{}<{}> registered no outputs'.format(class_name, node.pk))
+ return
+
+ click.echo('\n{link:25s} {node}'.format(link='Output link', node='Node pk and type'))
+ click.echo('{s}'.format(s='-' * 60))
+
+ for triple in sorted(outputs, key=lambda triple: triple.link_label):
+ click.echo('{:25s} {}<{}> '.format(triple.link_label, triple.node.__class__.__name__, triple.node.pk))
+
+
+def launch_process(process, daemon, **inputs):
+ """Launch a process with the given inputs.
+
+ If not sent to the daemon, the results will be displayed after the calculation finishes.
+
+ :param process: the process class or process builder.
+ :param daemon: boolean, if True will submit to the daemon instead of running in current interpreter.
+ :param inputs: inputs for the process if the process is not already a fully prepared builder.
+ """
+ from aiida.engine import launch, Process, ProcessBuilder
+
+ if isinstance(process, ProcessBuilder):
+ process_name = process.process_class.__name__
+ elif issubclass(process, Process):
+ process_name = process.__name__
+ else:
+ raise TypeError('invalid type for process: {}'.format(process))
+
+ if daemon:
+ node = launch.submit(process, **inputs)
+ click.echo('Submitted {}<{}> to the daemon'.format(process_name, node.pk))
+ else:
+ click.echo('Running a {}...'.format(process_name))
+ _, node = launch.run_get_node(process, **inputs)
+ echo_process_results(node)
diff --git a/aiida_fleur/cmdline/visualization/__init__.py b/aiida_fleur/cmdline/visualization/__init__.py
new file mode 100755
index 000000000..30654e4ca
--- /dev/null
+++ b/aiida_fleur/cmdline/visualization/__init__.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+"""
+Module with CLI commands for various visualizations of data types.
+"""
+# if in the future there are futher sub commands of plot, the current plot
+# command can become plot_fleur
+import click
+from aiida.cmdline.utils import decorators
+from aiida.cmdline.params import arguments
+
+
+@click.command('plot')
+@arguments.NODES('nodes')
+# help='The pks for the nodes to be parsed to plot_fleur')
+# type=click.Path(exists=True))
+@click.option('-f', 'filename', type=click.File('r'), default=None)
+@click.option('--save',
+ type=click.BOOL,
+ default=False,
+ show_default=True,
+ help='Should the result of plot_fleur be saved to a files.')
+@click.option('--show/--no-show', default=True, show_default=True, help='Show the output of plot_fleur.')
+@click.option('--show_dict/--no-show_dict', default=False, show_default=True, help='Show the output of plot_fleur.')
+@click.option('--bokeh', 'backend', flag_value='bokeh')
+@click.option('--matplotlib', 'backend', flag_value='matplotlib', default=True)
+#@decorators.with_dbenv()
+def cmd_plot(nodes, filename, save, show_dict, backend, show):
+ """
+ Invoke the plot_fleur command on given nodes
+ """
+ if backend != 'bokeh':
+ # Try to set a working GUI backend for matplotlib
+ # normally we assume to be on ipython which is not good.
+ # The order is arbitrary.
+ import matplotlib
+ gui_env = [
+ 'WebAgg', 'GTK3Agg', 'GTK3Cairo', 'MacOSX', 'Qt4Agg', 'Qt4Cairo', 'Qt5Agg', 'Qt5Cairo', 'TkAgg', 'TkCairo',
+ 'WX', 'WXAgg', 'WXCairo', 'nbAgg', 'agg', 'cairo', 'pdf', 'pgf', 'ps', 'svg'
+ ]
+ for gui in gui_env:
+ try:
+ print('testing', gui)
+ matplotlib.use(gui, force=True)
+ from matplotlib import pyplot as plt
+ break
+ except ImportError as ex:
+ print(ex)
+ continue
+ print('Using:', matplotlib.get_backend())
+
+ from aiida_fleur.tools.plot.fleur import plot_fleur
+
+ nodes = list(nodes)
+ nodesf = []
+ if filename is not None:
+ nodesf = filename.read().split()
+ filename.close()
+ nodes = nodes + nodesf
+ p = plot_fleur(nodes, save=save, show_dict=show_dict, backend=backend, show=show)
diff --git a/aiida_fleur/cmdline/workflows/__init__.py b/aiida_fleur/cmdline/workflows/__init__.py
new file mode 100755
index 000000000..e4e92b550
--- /dev/null
+++ b/aiida_fleur/cmdline/workflows/__init__.py
@@ -0,0 +1,172 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+"""
+Module with CLI commands to launch and inspect various aiida-fleur workchains.
+"""
+import click
+from aiida.cmdline.params.types import ProcessParamType
+from aiida.cmdline.params import arguments, options
+from aiida.cmdline.utils import decorators, echo
+from aiida import orm
+from aiida_fleur.cmdline.util import options as options_fl
+
+
+@click.group('workflow')
+def cmd_workflow():
+ """Commands to inspect aiida-fleur workchains."""
+
+
+# general further commands for fleur workchains
+
+
+@cmd_workflow.command('res')
+@arguments.PROCESS('process', type=ProcessParamType()
+ ) #, type=WorkflowParamType(sub_classes=('aiida.node:process.workflow.workchain',)))
+@click.option('--info/--no-info', default=False, help='Print an info header above each node.')
+@click.option('-l', '--label', 'label', type=str, help='Print only output dicts with a certain link_label.')
+@options_fl.SHOW()
+@options.DICT_KEYS()
+@options.DICT_FORMAT()
+@decorators.with_dbenv()
+def workchain_res(process, info, label, show, keys, fmt):
+ """Print data from Dict nodes returned or created by any fleur process."""
+
+ returned_dicts_info = []
+ returned_dicts = []
+ try:
+ results = process.get_outgoing().all()
+ except ValueError as exception:
+ echo.echo_critical(str(exception))
+ for result in results:
+ if isinstance(result.node, orm.Dict):
+ if label is not None:
+ if label == result.link_label:
+ returned_dicts.append(result.node.get_dict())
+ returned_dicts_info.append(result)
+ else:
+ returned_dicts.append(result.node.get_dict())
+ returned_dicts_info.append(result)
+
+ for i, re_dict in enumerate(returned_dicts):
+ if keys is not None:
+ try:
+ result = {k: re_dict[k] for k in keys}
+ except KeyError as exc:
+ echo.echo_critical("key '{}' was not found in the results dictionary".format(exc.args[0]))
+ else:
+ result = re_dict
+ if info:
+ echo.echo('# Info: {} {} dict:'.format(returned_dicts_info[i].link_label, returned_dicts_info[i].node))
+ echo.echo_dictionary(result, fmt=fmt)
+
+
+@cmd_workflow.command('inputdict')
+@arguments.PROCESS('process', type=ProcessParamType()
+ ) #, type=WorkflowParamType(sub_classes=('aiida.node:process.workflow.workchain',)))
+@click.option('--info/--no-info', default=False, help='Print an info header above each node.')
+@click.option('-l', '--label', 'label', type=str, help='Print only output dicts with a certain link_label.')
+@options_fl.SHOW()
+@options.DICT_KEYS()
+@options.DICT_FORMAT()
+@decorators.with_dbenv()
+def workchain_inputdict(process, info, label, show, keys, fmt):
+ """Print data from Dict nodes input into any fleur process."""
+ from aiida.orm import Dict
+
+ returned_dicts_info = []
+ returned_dicts = []
+ try:
+ results = process.get_incoming().all()
+ except ValueError as exception:
+ echo.echo_critical(str(exception))
+ for result in results:
+ if isinstance(result.node, orm.Dict):
+ if label is not None:
+ if label == result.link_label:
+ returned_dicts.append(result.node.get_dict())
+ returned_dicts_info.append(result)
+ else:
+ returned_dicts.append(result.node.get_dict())
+ returned_dicts_info.append(result)
+
+ for i, re_dict in enumerate(returned_dicts):
+ if keys is not None:
+ try:
+ result = {k: re_dict[k] for k in keys}
+ except KeyError as exc:
+ echo.echo_critical("key '{}' was not found in the results dictionary".format(exc.args[0]))
+ else:
+ result = re_dict
+ if info:
+ echo.echo('# Info: {} {} dict:'.format(returned_dicts_info[i].link_label, returned_dicts_info[i].node))
+ if show:
+ echo.echo_dictionary(result, fmt=fmt)
+
+
+'''
+@cmd_workflow.command('gen_wf_para')
+@arguments.ENTRYPOINTSTR('entrypoint', default='fleur.scf')
+@options.SHOW()
+@options.STORE()
+@options.CHECK_EXISTENCE()
+@options.KWARGS()
+@decorators.with_dbenv()
+def gen_wf_para_cmd(entrypoint, show, store, check_existence, kwargs):
+ """
+ Generates a default parameter wf parameter node for given entrypoint.
+ """
+ from aiida_fleur.tools.node_generators import generate_wf_para_node
+ from aiida.plugins import entry_point
+ try:
+ wf = entry_point.load_entry_point('aiida.workflows', prefix)
+ except ValueError:
+ echo.echo('here1')
+ try:
+ wf = entry_point.load_entry_point('aiida.calculations', prefix)
+ except ValueError:
+ echo.echo('here1')
+
+ wf_para = generate_wf_para_node(entrypoint=entrypoint, **kwargs)
+ if store:
+ wf_para.store()
+ echo.echo('Created wf para node')
+ else:
+ echo.echo('Created wf para node')
+ if show:
+ echo.echo_dictionary(wf.para.get_dict())
+
+
+
+@cmd_workflow.command('inputls')
+def inputls_wc():
+ """
+ Prints verdi node show for all workchain inputs.
+ """
+ click.echo('verdi aiida-fleur scf res')
+
+@cmd_workflow.command('show')
+def show_wc():
+ """
+ Shows the node ans structure of a workchain.
+ Similar to verdi node show
+ """
+ click.echo('verdi aiida-fleur scf show')
+
+
+@cmd_workflow.command('list')
+def list_wc():
+ """
+ Similar to the verdi process list command, but this has preset filters and
+ displays also some specific information about fleur workchains
+ """
+ click.echo('verdi aiida-fleur scf list')
+'''
diff --git a/aiida_fleur/common/constants.py b/aiida_fleur/common/constants.py
index 0a474ee13..26e135419 100644
--- a/aiida_fleur/common/constants.py
+++ b/aiida_fleur/common/constants.py
@@ -13,6 +13,25 @@
Here we collect physical constants which are used throughout the code
that way we ensure consitency
'''
+# at some point one should import these from masci-tools, or better scipy or ase to ensure,
+# that all judft plugins and tools take the same values, to make roundtrips consistent
+# NIST https://physics.nist.gov/cgi-bin/cuu/Value?hrev
+HTR_TO_EV = 27.211386245988 #(53)
+BOHR_A = 0.5291772108
+#Scipy bohr 5.29177210903e-11 m
+#Scipy htr 27.211386245988 eV
+# NIST BOHR 0.529177210903 #(80)
+#https://physics.nist.gov/cgi-bin/cuu/Value?bohrrada0
-htr_to_ev = 27.21138602
-bohr_a = 0.52917720903
+#Fleur
+#htr_eV = 27.21138602
+#bohr=0.5291772108
+#bohrtocm=0.529177e-8
+#pymatgen uses scipy.constants
+#ase: Bohr 0.5291772105638411
+#Hartree 27.211386024367243
+#Rydberg 13.605693012183622
+#1/Bohr
+#1.8897261258369282
+#aiida-core units:
+#bohr_to_ang = 0.52917720859
diff --git a/aiida_fleur/common/defaults.py b/aiida_fleur/common/defaults.py
new file mode 100644
index 000000000..fc45bee68
--- /dev/null
+++ b/aiida_fleur/common/defaults.py
@@ -0,0 +1,27 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Here default values are collected.
+Meaning is to centralize the defaults throughout the plugin more, to allow in the
+end that the user might be able to specify them in a file he provides
+'''
+default_options = {
+ 'resources': {
+ 'num_machines': 1,
+ 'num_mpiprocs_per_machine': 1
+ },
+ 'max_wallclock_seconds': 6 * 60 * 60,
+ 'queue_name': '',
+ 'custom_scheduler_commands': '',
+ 'import_sys_environment': False,
+ 'environment_variables': {}
+}
diff --git a/aiida_fleur/common/mapping.py b/aiida_fleur/common/mapping.py
index cb01e3015..59118a4b6 100644
--- a/aiida_fleur/common/mapping.py
+++ b/aiida_fleur/common/mapping.py
@@ -57,8 +57,8 @@ def prepare_process_inputs(process, inputs):
try:
process_spec = process.spec()
- except AttributeError:
- raise ValueError('process {} does not have a spec')
+ except AttributeError as exc:
+ raise ValueError('Process {} does not have a spec') from exc
for key, value in six.iteritems(inputs):
diff --git a/aiida_fleur/common/node_generators.py b/aiida_fleur/common/node_generators.py
new file mode 100644
index 000000000..23e8dc655
--- /dev/null
+++ b/aiida_fleur/common/node_generators.py
@@ -0,0 +1,97 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+This contains functions to generate certain node content, mostly dictionaries
+with defaults.
+These functions are usefull to expose one the commandline and to have defaults in one place
+'''
+# Todo: some of these can be moved to aiida-jutools
+# since for kkr they might be the same
+#todo, we allow kwargs for the nodes, maybe they should be validated
+from aiida import orm
+from aiida.plugins import WorkflowFactory
+from aiida.orm import QueryBuilder
+
+
+def generate_wf_option_node(computer=None, check_existence=True, **kwargs):
+ """Create a option node for a certain workflow or calculation entry point.
+
+ :param wf_entry_point: string the entry point to create the node for, default='fleur.scf'
+ :param computer: dict {computername, queue} to provide computer dependend defaults
+ :param kwargs: dict, further key word argument by which the node content will be updated
+
+ :returns: AiiDA Dict node
+ """
+ option_node_dict = generate_wf_option_dict(computer=computer, **kwargs)
+ option_node = orm.Dict(dict=option_node_dict)
+ if check_existence:
+ duplicate = QueryBuilder().append(orm.Dict, filters={'extras._aiida_hash': option_node._get_hash()}).first() # pylint: disable=protected-access
+ if duplicate:
+ option_node = duplicate[0]
+
+ return option_node
+
+
+def generate_wf_option_dict(computer=None, protocol_file=None, **kwargs):
+ """Create a option dict for a certain workflow or calculation entry point.
+
+ :param computer: dict {computername, queue} to provide computer dependend defaults
+ :param kwargs: dict, further key word argument by which the node content will be updated
+ :param protocol_file: str, path to json file containing a set of default options
+
+ :returns: python dict
+ """
+ # options usually do not differe between workflows, but depend on system size and machine.
+ # Also per project, therefore it would be nice to allow to provide a file and with a set of defaults.
+ # and this function should read them
+ from aiida_fleur.common.defaults import default_options
+
+ default_wf_dict = default_options.deepcopy()
+ #todo better rekursive merge?
+ default_wf_dict.update(kwargs)
+
+ return default_wf_dict
+
+
+def generate_wf_para_dict(wf_entry_point='fleur.scf', **kwargs):
+ """Create a wf parameter dict for a certain workflow or calculation entry point.
+
+ :param wf_entry_point: string the entry point to create the node for, default='fleur.scf'
+ :param kwargs: dict, further key word argument by which the node content will be updated
+
+ :returns: python dict
+ """
+
+ wf = WorkflowFactory(wf_entry_point)
+ default_wf_dict = wf._default_wf_para
+ #todo better rekursive merge?
+ default_wf_dict.update(kwargs)
+
+ return default_wf_dict
+
+
+def generate_wf_para_node(wf_entry_point='fleur.scf', check_existence=True, **kwargs):
+ """Create a wf parameter node for a certain workflow or calculation entry point.
+
+ :param wf_entry_point: string the entry point to create the node for, default='fleur.scf'
+ :param kwargs: dict, further key word argument by which the node content will be updated
+
+ :returns: AiiDA Dict node
+ """
+ wf_para_node_dict = generate_wf_para_dict(wf_entry_point=wf_entry_point, check_existence=check_existence, **kwargs)
+ wf_para_node = orm.Dict(dict=wf_para_node_dict)
+ if check_existence:
+ duplicate = QueryBuilder().append(orm.Dict, filters={'extras._aiida_hash': wf_para_node._get_hash()}).first() # pylint: disable=protected-access
+ if duplicate:
+ wf_para_node = duplicate[0]
+
+ return wf_para_node
diff --git a/aiida_fleur/common/workchain/base/restart.py b/aiida_fleur/common/workchain/base/restart.py
index 9841b7c7f..0114e4ddc 100644
--- a/aiida_fleur/common/workchain/base/restart.py
+++ b/aiida_fleur/common/workchain/base/restart.py
@@ -56,7 +56,7 @@ class BaseRestartWorkChain(WorkChain):
_error_handler_entry_point = None
def __init__(self, *args, **kwargs):
- super(BaseRestartWorkChain, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
if self._calculation_class is None or not issubclass(self._calculation_class, (CalcJob, WorkChain)):
raise ValueError('no valid CalcJob or WorkChain class defined for `_calculation_class` attribute')
@@ -65,7 +65,7 @@ def __init__(self, *args, **kwargs):
@override
def load_instance_state(self, saved_state, load_context):
- super(BaseRestartWorkChain, self).load_instance_state(saved_state, load_context)
+ super().load_instance_state(saved_state, load_context)
self._load_error_handlers()
def _load_error_handlers(self):
@@ -86,8 +86,7 @@ def _load_error_handlers(self):
@classmethod
def define(cls, spec):
# yapf: disable
- # pylint: disable=bad-continuation
- super(BaseRestartWorkChain, cls).define(spec)
+ super().define(spec)
spec.input('max_iterations', valid_type=orm.Int, default=lambda: orm.Int(3),
help='Maximum number of iterations the work chain will restart the calculation to finish successfully.')
spec.input('clean_workdir', valid_type=orm.Bool, default=lambda: orm.Bool(False),
@@ -121,8 +120,8 @@ def run_calculation(self):
try:
unwrapped_inputs = self.ctx.inputs
- except AttributeError:
- raise AttributeError('no calculation input dictionary was defined in `self.ctx.inputs`')
+ except AttributeError as exc:
+ raise AttributeError('no calculation input dictionary was defined in `self.ctx.inputs`') from exc
inputs = prepare_process_inputs(self._calculation_class, unwrapped_inputs)
calculation = self.submit(self._calculation_class, **inputs)
@@ -201,7 +200,7 @@ def results(self):
def on_terminated(self):
"""Clean the working directories of all child calculations if `clean_workdir=True` in the inputs."""
- super(BaseRestartWorkChain, self).on_terminated()
+ super().on_terminated()
if self.inputs.clean_workdir.value is False:
self.report('remote folders will not be cleaned')
diff --git a/aiida_fleur/data/fleurinp.py b/aiida_fleur/data/fleurinp.py
index f92858692..7e4083bd0 100644
--- a/aiida_fleur/data/fleurinp.py
+++ b/aiida_fleur/data/fleurinp.py
@@ -35,7 +35,7 @@
from aiida_fleur.tools.xml_util import replace_tag
from aiida_fleur.fleur_schema.schemafile_index import get_internal_search_paths, get_schema_paths
-from aiida_fleur.common.constants import bohr_a as BOHR_A
+from aiida_fleur.common.constants import BOHR_A
class FleurinpData(Data):
@@ -82,7 +82,7 @@ def __init__(self, **kwargs):
files.append(filename)
break
node = kwargs.pop('node', None)
- super(FleurinpData, self).__init__(**kwargs)
+ super().__init__(**kwargs)
search_paths = []
ifolders = get_internal_search_paths()
@@ -431,8 +431,12 @@ def _set_inp_dict(self):
parser = etree.XMLParser(attribute_defaults=True, encoding='utf-8')
# dtd_validation=True
with self.open(path='inp.xml', mode='r') as inpxmlfile:
- tree_x = etree.parse(inpxmlfile, parser)
-
+ try:
+ tree_x = etree.parse(inpxmlfile, parser)
+ except etree.XMLSyntaxError as exc:
+ # prob inp.xml file broken
+ err_msg = ('The inp.xml file is probably broken, could not parse it to an xml etree.')
+ raise InputValidationError(err_msg) from exc
# relax.xml should be available to be used in xinclude
# hence copy relax.xml from the retrieved node into the temp file
fo = tempfile.NamedTemporaryFile(mode='w', delete=False)
@@ -464,7 +468,8 @@ def _set_inp_dict(self):
tree_x = etree.fromstring(inpxmlfile, parser_on_fly)
except etree.XMLSyntaxError as msg:
message = msg
- raise InputValidationError('Input file does not validate against the schema: {}'.format(message))
+ raise InputValidationError(
+ 'Input file does not validate against the schema: {}'.format(message)) from msg
raise InputValidationError('Input file is not validated against the schema.' 'Reason is unknown')
@@ -491,7 +496,7 @@ def _validate(self):
"""
#from aiida.common.exceptions import ValidationError
- super(FleurinpData, self)._validate()
+ super()._validate()
if 'inp.xml' in self.files:
# has_inpxml = True # does nothing so far
@@ -943,108 +948,6 @@ def get_parameterdata(fleurinp):
return fleurinp.get_parameterdata_ncf()
- @cf
- def set_kpointsdata(self, fleurinp_orgi, KpointsDataNode):
- """
- This calc function writes the all the kpoints from a :class:`~aiida.orm.KpointsData` node
- in the ``inp.xml`` file as a kpointslist. It replaces kpoints written in the
- ``inp.xml`` file. The output :class:`~aiida_fleur.data.fleurinp.FleurinpData` is stored in
- the database.
-
- Currently it is the users resposibility to provide a full
- :class:`~aiida.orm.KpointsData` node with weights.
-
- :param KpointsDataNode: :class:`~aiida.orm.KpointsData` node to be written into ``inp.xml``
- :returns: modified :class:`~aiida_fleur.data.fleurinp.FleurinpData` node
- """
- from aiida.orm import KpointsData
- #from aiida.common.exceptions import InputValidationError
-
- # all hardcoded xpaths used and attributes names:
- fleurinp = fleurinp_orgi.copy()
- kpointlist_xpath = '/fleurInput/calculationSetup/bzIntegration/kPointList'
- #kpoint_tag = 'kPoint'
- #kpointlist_attrib_posscale = 'posScale'
- #kpointlist_attrib_weightscale = 'weightScale'
- #kpointlist_attrib_count = 'count'
- #kpoint_attrib_weight = 'weight'
-
- #### method layout: #####
- # Check if Kpoints node
- # get kpoints, weights, inp.xml
-
- # replace the kpoints tag.(delete old write new)
- # kpoint list posScale, wightScale, count
- #
- # 17.000000 0.000000 0.000000
-
- # add new inp.xml to fleurinpdata
-
- if not isinstance(KpointsDataNode, KpointsData):
- raise InputValidationError('The node given is not a valid KpointsData node.')
-
- if 'inp.xml' in fleurinp.files:
- # read in inpxml
- if fleurinp._schema_file_path: # Schema there, parse with schema
- xmlschema_doc = etree.parse(fleurinp._schema_file_path)
- xmlschema = etree.XMLSchema(xmlschema_doc)
- parser = etree.XMLParser(schema=xmlschema,
- attribute_defaults=True,
- remove_blank_text=True,
- encoding='utf-8')
- with fleurinp.open(path='inp.xml', mode='r') as inpxmlfile:
- tree = etree.parse(inpxmlfile, parser)
- else: # schema not there, parse without
- print('parsing inp.xml without XMLSchema')
- parser = etree.XMLParser(attribute_defaults=True, remove_blank_text=True, encoding='utf-8')
- with self.open(path='inp.xml', mode='r') as inpxmlfile:
- tree = etree.parse(inpxmlfile, parser)
- #root = tree.getroot()
- else:
- raise InputValidationError('No inp.xml file yet specified, to add kpoints to.')
-
- #cell_k = KpointsDataNode.cell
-
- # TODO: shall we check if cell is the same as cell from structure?
- # or is that to narrow?
-
- kpoint_list = KpointsDataNode.get_kpoints(also_weights=True, cartesian=False)
- nkpts = len(kpoint_list[0])
- totalw = 0
- for weight in kpoint_list[1]:
- totalw = totalw + weight
- #weightscale = totalw
-
- new_kpo = etree.Element('kPointList', posScale='1.000', weightScale='1.0', count='{}'.format(nkpts))
- for i, kpos in enumerate(kpoint_list[0]):
- new_k = etree.Element('kPoint', weight='{}'.format(kpoint_list[1][i]))
- new_k.text = '{} {} {}'.format(kpos[0], kpos[1], kpos[2])
- new_kpo.append(new_k)
-
- new_tree = replace_tag(tree, kpointlist_xpath, new_kpo)
- # use _write_new_fleur_xmlinp_file(fleurinp, inp_file_xmltree, fleur_change_dic):
-
- # TODO this should be sourced out to other methods.
- # somehow directly writing inp.xml does not work, create new one
- inpxmlfile = os.path.join(fleurinp._get_folder_pathsubfolder.abspath, 'temp_inp.xml')
-
- # write new inp.xml, schema evaluation will be done when the file gets added
- new_tree.write(inpxmlfile, pretty_print=True)
- print(('wrote tree to' + str(inpxmlfile)))
-
- # delete old inp.xml file, not needed anymore
- # TODO maybe do some checks before
- fleurinp.del_file('inp.xml')
-
- # now the new inp.xml file is added and with that the inpxml_dict will
- # be overwritten, and the file validated
- fleurinp._add_path(str(inpxmlfile), 'inp.xml')
-
- # remove temporary inp.xml file
- os.remove(inpxmlfile)
-
- return fleurinp
-
def get_tag(self, xpath):
"""
Tries to evaluate an xpath expression for ``inp.xml`` file. If it fails it logs it.
@@ -1071,10 +974,10 @@ def get_tag(self, xpath):
try:
return_value = root.xpath(xpath)
- except etree.XPathEvalError:
+ except etree.XPathEvalError as exc:
raise InputValidationError('There was a XpathEvalError on the xpath: {} \n Either it does '
'not exist, or something is wrong with the expression.'
- ''.format(xpath))
+ ''.format(xpath)) from exc
if len(return_value) == 1:
return return_value
diff --git a/aiida_fleur/data/fleurinpmodifier.py b/aiida_fleur/data/fleurinpmodifier.py
index c2fd569e8..d95f4c3af 100644
--- a/aiida_fleur/data/fleurinpmodifier.py
+++ b/aiida_fleur/data/fleurinpmodifier.py
@@ -23,6 +23,7 @@
from lxml import etree
from aiida.plugins import DataFactory
+from aiida import orm
from aiida.engine.processes.functions import calcfunction as cf
from aiida_fleur.data.fleurinp import FleurinpData
@@ -40,6 +41,7 @@ def __init__(self, original):
self._original = original
self._tasks = []
+ self._other_nodes = {}
@staticmethod
def apply_modifications(fleurinp_tree_copy, nmmp_lines_copy, modification_tasks, schema_tree=None):
@@ -153,6 +155,10 @@ def set_kpath1(fleurinp_tree_copy, kpath, count, gamma):
fleurinp_tree_copy = set_kpath(fleurinp_tree_copy, kpath, count, gamma)
return fleurinp_tree_copy
+ def set_kpointsdata1(fleurinp_tree_copy, kpointsdata_uuid):
+ fleurinp_tree_copy = set_kpointsdata_f(fleurinp_tree_copy, kpointsdata_uuid)
+ return fleurinp_tree_copy
+
def set_nmmpmat1(fleurinp_tree_copy, nmmp_lines_copy, species_name, orbital,\
spin, occStates, denmat, phi, theta):
nmmp_lines_copy = set_nmmpmat(fleurinp_tree_copy, nmmp_lines_copy, species_name, orbital,\
@@ -179,8 +185,9 @@ def set_nmmpmat1(fleurinp_tree_copy, nmmp_lines_copy, species_name, orbital,\
'shift_value_species_label': shift_value_species_label1,
'set_nkpts': set_nkpts1,
'set_kpath': set_kpath1,
+ 'set_kpointsdata': set_kpointsdata1,
'add_num_to_att': add_num_to_att1,
- 'set_nmmpmat': set_nmmpmat1,
+ 'set_nmmpmat': set_nmmpmat1
}
workingtree = fleurinp_tree_copy
@@ -192,8 +199,8 @@ def set_nmmpmat1(fleurinp_tree_copy, nmmp_lines_copy, species_name, orbital,\
for task in modification_tasks:
try:
action = actions[task[0]]
- except KeyError:
- raise ValueError('Unknown task {}'.format(task[0]))
+ except KeyError as exc:
+ raise ValueError('Unknown task {}'.format(task[0])) from exc
if task[0] == 'set_nmmpmat':
workingnmmp = action(workingtree, workingnmmp, *task[1:])
@@ -203,14 +210,16 @@ def set_nmmpmat1(fleurinp_tree_copy, nmmp_lines_copy, species_name, orbital,\
if schema_tree:
try:
xmlschema.assertValid(clear_xml(workingtree))
- except etree.DocumentInvalid:
- print('changes were not valid: {}'.format(modification_tasks))
- raise
+ except etree.DocumentInvalid as exc:
+ msg = 'Changes were not valid: {}'.format(modification_tasks)
+ print(msg)
+ raise etree.DocumentInvalid(msg) from exc
try:
validate_nmmpmat(workingtree, workingnmmp)
- except ValueError:
- print('changes were not valid (n_mmp_mat file is not compatible): {}'.format(modification_tasks))
- raise
+ except ValueError as exc:
+ msg = 'Changes were not valid (n_mmp_mat file is not compatible): {}'.format(modification_tasks)
+ print(msg)
+ raise ValueError(msg) from exc
return workingtree, workingnmmp
@@ -237,8 +246,10 @@ def get_avail_actions(self):
'shift_value': self.shift_value,
'shift_value_species_label': self.shift_value_species_label,
'set_nkpts': self.set_nkpts,
+ 'set_kpath': self.set_kpath,
+ 'set_kpointsdata': self.set_kpointsdata,
'add_num_to_att': self.add_num_to_att,
- 'set_nmmpmat': self.set_nmmpmat,
+ 'set_nmmpmat': self.set_nmmpmat
}
return outside_actions
@@ -455,6 +466,21 @@ def set_kpath(self, kpath, count, gamma='F'):
"""
self._tasks.append(('set_kpath', kpath, count, gamma))
+ def set_kpointsdata(self, kpointsdata_uuid):
+ """
+ Appends a :py:func:`~aiida_fleur.data.fleurinpmodifier.set_kpointsdata_f()` to
+ the list of tasks that will be done on the FleurinpData.
+
+ :param kpointsdata_uuid: an :class:`aiida.orm.KpointsData` or node uuid, since the node is self cannot be be serialized in tasks.
+ """
+ from aiida.orm import KpointsData, load_node
+
+ if isinstance(kpointsdata_uuid, KpointsData):
+ kpointsdata_uuid = kpointsdata_uuid.uuid
+ # Be more careful? Needs to be stored, otherwise we cannot load it
+ self._other_nodes['kpoints'] = load_node(kpointsdata_uuid)
+ self._tasks.append(('set_kpointsdata', kpointsdata_uuid))
+
def add_num_to_att(self, xpathn, attributename, set_val, mode='abs', occ=None):
"""
Appends a :py:func:`~aiida_fleur.tools.xml_util.add_num_to_att()` to
@@ -552,16 +578,20 @@ def freeze(self):
:return: stored :class:`~aiida_fleur.data.fleurinp.FleurinpData` with applied changes
"""
- modifications = DataFactory('dict')(dict={'tasks': self._tasks})
+ modifications = orm.Dict(dict={'tasks': self._tasks})
+ #print(self._tasks)
modifications.description = 'Fleurinpmodifier Tasks and inputs of these.'
modifications.label = 'Fleurinpdata modifications'
# This runs in a inline calculation to keep provenance
- out = modify_fleurinpdata(original=self._original,
- modifications=modifications,
- metadata={
- 'label': 'fleurinp modifier',
- 'description': 'This calcfunction modified an Fleurinpdataobject'
- })
+ print(self._original)
+ inputs = dict(original=self._original,
+ modifications=modifications,
+ metadata={
+ 'label': 'fleurinp modifier',
+ 'description': 'This calcfunction modified an Fleurinpdataobject'
+ },
+ **self._other_nodes)
+ out = modify_fleurinpdata(**inputs)
return out
def undo(self, revert_all=False):
@@ -574,20 +604,21 @@ def undo(self, revert_all=False):
self._tasks = []
else:
if self._tasks:
- self._tasks.pop()
+ task = self._tasks.pop()
+ #TODO delete nodes from other nodes
#del self._tasks[-1]
return self._tasks
@cf
-def modify_fleurinpdata(original, modifications):
+def modify_fleurinpdata(original, modifications, **kwargs):
"""
A CalcFunction that performs the modification of the given FleurinpData and stores
the result in a database.
:param original: a FleurinpData to be modified
:param modifications: a python dictionary of modifications in the form of {'task': ...}
-
+ :param kwargs: dict of other aiida nodes to be linked to the modifications
:returns new_fleurinp: a modified FleurinpData that is stored in a database
"""
@@ -611,9 +642,10 @@ def modify_fleurinpdata(original, modifications):
try:
xmlschema.assertValid(clear_xml(tree))
- except etree.DocumentInvalid:
- print('Input file is not validated against the schema')
- raise
+ except etree.DocumentInvalid as exc:
+ msg = 'Input file is not validated against the schema'
+ print(msg)
+ raise etree.DocumentInvalid(msg) from exc
try:
with new_fleurinp.open(path='n_mmp_mat', mode='r') as n_mmp_file:
@@ -645,3 +677,51 @@ def modify_fleurinpdata(original, modifications):
new_fleurinp.description = 'Fleurinpdata with modifications (see inputs of modify_fleurinpdata)'
return new_fleurinp
+
+
+def set_kpointsdata_f(fleurinp_tree_copy, kpointsdata_uuid):
+ """This calc function writes all kpoints from a :class:`~aiida.orm.KpointsData` node
+ in the ``inp.xml`` file as a kpointslist. It replaces kpoints written in the
+ ``inp.xml`` file. Currently it is the users responsibility to provide a full
+ :class:`~aiida.orm.KpointsData` node with weights.
+
+ :param fleurinp_tree_copy: fleurinp_tree_copy
+ :param kpointsdata_uuid: node identifier or :class:`~aiida.orm.KpointsData` node to be written into ``inp.xml``
+ :return: modified xml tree
+ """
+ # TODO: check on weights,
+ # also fleur allows for several kpoint sets, lists, paths and meshes,
+ # support this.
+ from aiida.orm import KpointsData, load_node
+ from aiida.common.exceptions import InputValidationError
+ from aiida_fleur.tools.xml_util import replace_tag
+
+ # all hardcoded xpaths used and attributes names:
+ kpointlist_xpath = '/fleurInput/calculationSetup/bzIntegration/kPointList'
+
+ # replace the kpoints tag.(delete old write new)
+ #
+ # 17.000000 0.000000 0.000000
+ # add new inp.xml to fleurinpdata
+ if not isinstance(kpointsdata_uuid, KpointsData):
+ KpointsDataNode = load_node(kpointsdata_uuid)
+ else:
+ KpointsDataNode = kpointsdata_uuid
+
+ if not isinstance(KpointsDataNode, KpointsData):
+ raise InputValidationError('The node given is not a valid KpointsData node.')
+
+ kpoint_list = KpointsDataNode.get_kpoints(also_weights=True, cartesian=False)
+ nkpts = len(kpoint_list[0])
+ totalw = 0
+ for weight in kpoint_list[1]:
+ totalw = totalw + weight
+ #weightscale = totalw
+ # fleur will re weight? renormalize?
+ new_kpo = etree.Element('kPointList', posScale='1.000', weightScale='1.0', count='{}'.format(nkpts))
+ for i, kpos in enumerate(kpoint_list[0]):
+ new_k = etree.Element('kPoint', weight='{}'.format(kpoint_list[1][i]))
+ new_k.text = '{} {} {}'.format(kpos[0], kpos[1], kpos[2])
+ new_kpo.append(new_k)
+ new_tree = replace_tag(fleurinp_tree_copy, kpointlist_xpath, new_kpo)
+ return new_tree
diff --git a/aiida_fleur/parsers/fleur.py b/aiida_fleur/parsers/fleur.py
index e408558f5..e810febb3 100644
--- a/aiida_fleur/parsers/fleur.py
+++ b/aiida_fleur/parsers/fleur.py
@@ -22,12 +22,14 @@
import os
import re
import json
+import numpy as np
from datetime import date
from lxml import etree
from aiida.parsers import Parser
from aiida.orm import Dict, BandsData
from aiida.common.exceptions import NotExistent
+from aiida_fleur.common.constants import HTR_TO_EV
class FleurParser(Parser):
@@ -139,7 +141,8 @@ def parse(self, **kwargs):
mpiprocs = self.node.get_attribute('resources').get('num_mpiprocs_per_machine', 1)
kb_used = 0.0
- with output_folder.open('out.xml', 'r') as out_file: # lazy out.xml parsing
+ with output_folder.open(FleurCalculation._OUTXML_FILE_NAME,
+ 'r') as out_file: # lazy out.xml parsing
outlines = out_file.read()
try:
line_avail = re.findall(r' 0:
+ new_parameterd[atomlistname] = val
+ ids.remove(el_id)
+ symbol_possible_ids[symbol] = ids
+ kind_found = True
+ break # we assume the user is smart and provides a para node,
+ # which incorporates the symmetry breaking already
+ # but we need to see all atom lists to know if it is there...
+ if kind_found:
+ continue
+ for key in sorted(para):
+ val = para[key]
+ if 'atom' in key:
+ if val.get('element', None) != symbol:
+ if val.get('z', None) != _atomic_numbers.get(symbol):
+ continue
+ el_id = str(val.get('id', '0.0'))
+ el_id = int(el_id.split('.')[1])
+ ids = symbol_possible_ids.get(symbol)
+ # copy parameter of symbol and add id
+ # this would be the lowest predefined atom list of an element
+ val_new = {}
+ val_new.update(val)
+ charge = _atomic_numbers.get((val.get('element', None)))
+ if charge is None:
+ charge = val.get('z', None)
+ idp = '{}.{}'.format(charge, ids[0])
+ ids.remove(el_id)
+ idp = float('{0:.2f}'.format(float(idp)))
+ # dot cannot be stored in AiiDA dict...
+ val_new.update({u'id': idp})
+ atomlistname = 'atom{}'.format(i)#id_a)
+ # Since there are other atoms list also find the next
+ # free atom key.
+ #j = 0
+ #while new_parameterd.get(atomlistname, {}):
+ # j = j + 1
+ # atomlistname = 'atom{}'.format(id_a + i)
+ #symbol_new_kinds_names = new_kinds_names.get(symbol, [])
+ # print(symbol_new_kinds_names)
+ #if symbol_new_kinds_names and ((len(symbol_new_kinds_names)) == symbol_count[symbol]):
+ # species_name = symbol_new_kinds_names[symbol_count[symbol] - 1]
+ # val_new.update({u'name': species_name})
+ new_parameterd[atomlistname] = val_new
+ break # max one new atom list per kind
+'''
+'''
+ # add other non atom keys from original parameterdata
+ for key, val in para.items():
+ if 'atom' not in key:
+ new_parameterd[key] = val
+ elif add_atom_base_lists:
+ if not 'id' in val:
+ new_parameterd[key] = val
para_new = Dict(dict=new_parameterd)
else:
para_new = None
+ print(new_parameterd)
new_structure.label = structure.label
new_structure.description = structure.description + 'more kinds, less sym'
return new_structure, para_new
+'''
def find_equi_atoms(structure): # , sitenumber=0, position=None):
@@ -663,9 +978,11 @@ def get_all_miller_indices(structure, highestindex):
"""
wraps the pymatgen function get_symmetrically_distinct_miller_indices for an AiiDa structure
"""
+ from pymatgen.core.surface import get_symmetrically_distinct_miller_indices
return get_symmetrically_distinct_miller_indices(structure.get_pymatgen_structure(), highestindex)
+'''
def create_all_slabs_buggy(initial_structure,
miller_index,
min_slab_size_ang,
@@ -705,6 +1022,7 @@ def create_all_slabs_buggy(initial_structure,
film_struc.pbc = (True, True, False)
aiida_strucs[slab.miller_index] = film_struc
return aiida_strucs
+'''
def create_all_slabs(initial_structure,
@@ -728,9 +1046,9 @@ def create_all_slabs(initial_structure,
indices = get_all_miller_indices(initial_structure, miller_index)
for index in indices:
slab = create_slap(initial_structure, index, min_slab_size_ang, min_vacuum_size, min_slab_size_ang)
- film_struc = StructureData(pymatgen_structure=slab)
- film_struc.pbc = (True, True, False)
- aiida_strucs[slab.miller_index] = film_struc
+ #film_struc = StructureData(pymatgen_structure=slab)
+ #film_struc.pbc = (True, True, False)
+ aiida_strucs[index] = slab
return aiida_strucs
@@ -869,7 +1187,7 @@ def create_manual_slab_ase(lattice='fcc',
*_, layer_occupancies = get_layers(structure)
if replacements is not None:
- keys = six.viewkeys(replacements)
+ keys = list(replacements.keys())
if max((abs(int(x)) for x in keys)) >= len(layer_occupancies):
raise ValueError('"replacements" has to contain numbers less than number of layers:'
' {}'.format(len(layer_occupancies)))
@@ -894,7 +1212,7 @@ def create_manual_slab_ase(lattice='fcc',
*_, layer_occupancies = get_layers(structure)
layer_occupancies.insert(0, 0)
- for i, at_type in six.iteritems(replacements):
+ for i, at_type in replacements.items():
if isinstance(i, str):
i = int(i)
if i < 0:
@@ -1271,6 +1589,7 @@ def request_average_bond_length(main_elements, sub_elements, user_api_key):
return Dict(dict=bond_data)
+'''
def estimate_mt_radii(structure, stepsize=0.05):
"""
# TODO implement
@@ -1311,3 +1630,4 @@ def find_common_mt(structures):
"""
return None
+'''
diff --git a/aiida_fleur/tools/check_existence.py b/aiida_fleur/tools/check_existence.py
deleted file mode 100644
index 9af938de1..000000000
--- a/aiida_fleur/tools/check_existence.py
+++ /dev/null
@@ -1,252 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-"""
-DO NOT USE, this is crab so far. The development was stoped because this is done
-with AiiDA 'caching' now.
-
-Here are methods to check the existence of something in the database
-example if a (successful) SCF with the same inputs exists
-
-Since cashing is not there for data yet, and below are some basic querries I
-leave the code here for now.
-"""
-from __future__ import absolute_import
-from aiida.plugins import DataFactory
-from aiida.orm import QueryBuilder
-from aiida.engine import CalcJob
-from aiida.orm import Node
-'''
-def check_existence_calc(input_nodes, successful=True):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: input_nodes : List of input nodes
-
- returns output nodes
- """
- #TODO: some checks and inputnodes could be parsed in different formats
- inputnodesuuid = [node.uuid for node in input_nodes]
-
- qb=QueryBuilder()
- qb.append(
- JobCalculation, tag='calc', project='*',
- filters={'state' : {'==':'FINISHED'}})
-
- for idx, uuid in enumerate(inputnodesuuid):
- qb.append(Node, input_of='calc', filters={'uuid':uuid},
- tag='input_{}'.format(idx))
-
- qb.order_by({JobCalculation:'ctime'})
- res = qb.all()
- if res:
- return res[-1][0].get_outputs()
- else:
- return None
-
-def check_existence_wf(input_nodes, successful=True):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: input_nodes : List of input nodes
-
- returns output nodes
- """
- #TODO: some checks and inputnodes could be parsed in different formats
- inputnodesuuid = [node.uuid for node in input_nodes]
-
- qb=QueryBuilder()
- qb.append(
- JobCalculation, tag='calc', project='*',
- filters={'state' : {'==':'FINISHED'}})
-
- for idx, uuid in enumerate(inputnodesuuid):
- qb.append(Node, input_of='calc', filters={'uuid':uuid}, tag='input_{}'.format(idx))
-
- qb.order_by({JobCalculation:'ctime'})
- res = qb.all()
- if res:
- return res[-1][0].get_outputs()
- else:
- return None
-
-'''
-'''
-def intersectlist(l1, l2):
- common = []
- for element in l1:
- if element in l2:
- common.append(element)
- return common
-
-def check_existence_calc(input_nodes, successful=True):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: input_nodes : List of input nodes
-
- returns output nodes
- """
- inputnodesuuid = [node.uuid for node in input_nodes]
- overall_results = []
-
- for node in inputnodesuuid:
- suc = successful
- qb=QueryBuilder()
- qb.append(Node,
- filters={
- 'uuid' : {'==': node},
- },
- tag='input')
- if suc:
- qb.append(
- JobCalculation,
- filters={
- 'state' : {'==':'FINISHED'}
- },
- output_of='input')
- else:
- qb.append(
- JobCalculation,
- output_of='input',
- project=['uuid'])
- res = qb.all()
- if res: # if there is no node with such an input return
- resnodesuuid = [node[0].uuid for node in res] # needed for common list parts
- overall_results.append(resnodesuuid)
- else:
- return None
-
- intersect = overall_results[0]
- if len(overall_results) > 1:
- for res in overall_results[1:]:
- intersect = intersectlist(intersect, res)
- qb1=QueryBuilder()
- qb1.append(
- JobCalculation,
- filters={
- 'uuid' : {'in': intersect}
- })
- res = qb1.all()
- # we
- return res[0][0].outputs()
-'''
-'''
-def check_existence(target_nodetype, input_nodes, successful=False):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: target_nodetype
- param: input_nodes : List of input nodes
-
- returns output nodes
-
- Hints; successful is only for calculations types
- """
- inputnodesuuid = [node.uuid for node in input_nodes]
- qb=QueryBuilder()
- qb.append(Node,
- filters={
- 'uuid' : {'in': inputnodesuuid},
- },
- tag='input')
- if successful:
- qb.append(
- target_nodetype,
- filters={
- 'state' : {'==':'FINISHED'}
- },
- output_of='input')
- else:
- qb.append(
- target_nodetype,
- output_of='input')
- res = qb.all()
- print(len(res))
- if res:
- return res[0][0].ouputs()
- else:
- return None
-
-def check_existence_calc(input_nodes, successful=True):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: input_nodes : List of input nodes
-
- returns output nodes
- """
- inputnodesuuid = [node.uuid for node in input_nodes]
- qb=QueryBuilder()
- qb.append(Node,
- filters={
- 'uuid' : {'in': inputnodesuuid},
- },
- tag='input')
- if successful:
- qb.append(
- JobCalculation,
- filters={
- 'state' : {'==':'FINISHED'}
- },
- output_of='input')
- else:
- qb.append(
- JobCalculation,
- output_of='input')
-
- res = qb.all()
- print(len(res))
- if res:
- return res[0][0].ouputs()
- else:
- return None
-
-def check_existence_wf(target_nodetype, input_nodes, successful=True):
- """
- This methods checks in the database waether a certain type of node with the given
- input nodes already exists. If yes it returns the output nodes of that node.
-
- param: input_nodes : List of input nodes
-
- returns output nodes
- """
- inputnodesuuid = [node.uuid for node in input_nodes]
- qb=QueryBuilder()
- qb.append(Node,
- filters={
- 'uuid' : {'in': inputnodesuuid},
- },
- tag='input')
- if successful:
- qb.append(
- target_nodetype,
- filters={
- 'state' : {'==':'FINISHED'}
- },
- output_of='input')
- else:
- qb.append(
- target_nodetype,
- output_of='input')
- res = qb.all()
- print(len(res))
- if res:
- return res[0][0].ouputs()
- else:
- return None
-'''
diff --git a/aiida_fleur/tools/common_aiida.py b/aiida_fleur/tools/common_aiida.py
index 25549bb71..997d76e4d 100644
--- a/aiida_fleur/tools/common_aiida.py
+++ b/aiida_fleur/tools/common_aiida.py
@@ -192,6 +192,7 @@ def create_group(name, nodes, description=None, add_if_exist=False):
"""
Creates a group for a given node list.
+ !!! Now aiida-core has these functionality, use it from there instead!!!
So far this is only an AiiDA verdi command.
:params name: string name for the group
@@ -246,6 +247,8 @@ def create_group(name, nodes, description=None, add_if_exist=False):
def get_nodes_from_group(group, return_format='uuid'):
"""
Returns a list of pk or uuid of a nodes in a given group. Since 1.1.0, this function does
+ !!! Now aiida-core has these functionality, use it from there instead!!!
+
not load a group using the label or any other identification. Use Group.objects.get(filter=ID) to
pre-load this, available filters are: id, uuid, label, type_string, time, description, user_id.
"""
diff --git a/aiida_fleur/tools/common_fleur_wf.py b/aiida_fleur/tools/common_fleur_wf.py
index 34e5cbf08..05096931a 100644
--- a/aiida_fleur/tools/common_fleur_wf.py
+++ b/aiida_fleur/tools/common_fleur_wf.py
@@ -139,7 +139,7 @@ def get_inputs_fleur(code,
return inputs
-def get_inputs_inpgen(structure, inpgencode, options, label='', description='', params=None, **kwargs):
+def get_inputs_inpgen(structure, inpgencode, options, label='', description='', settings=None, params=None, **kwargs):
'''
Assembles the input dictionary for Fleur Calculation.
@@ -167,7 +167,8 @@ def get_inputs_inpgen(structure, inpgencode, options, label='', description='',
inputs.code = inpgencode
if params:
inputs.parameters = params
-
+ if settings:
+ inputs.settings = settings
if description:
inputs.metadata.description = description
else:
@@ -194,69 +195,6 @@ def get_inputs_inpgen(structure, inpgencode, options, label='', description='',
return inputs
-def get_scheduler_extras(code, resources, extras=None, project='jara0172'):
- """
- This is a utility function with the goal to make prepare the right resource
- and scheduler extras for a given computer.
- Since this is user dependend you might want to create your own.
-
- return: dict, custom scheduler commands
- """
- if extras is None:
- extras = {}
- nnodes = resources.get('num_machines', 1)
-
- # TODO memory has to be done better...
- mem_per_node = 120000 # max recommend 126000 MB on claix jara-clx nodes
- mem_per_process = mem_per_node / 24
- if not extras:
- # use defaults # TODO add other things, span, pinnning... openmp
- extras = {
- 'lsf': ('#BSUB -P {} \n#BSUB -M {} \n'
- '#BSUB -a intelmpi'.format(project, mem_per_process)),
- 'torque': '',
- 'direct': ''
- }
-
- # get the scheduler type from the computer the code is run on.
- com = code.computer
- # com_name = com.get_name()
- scheduler_type = com.get_scheduler_type()
-
- default_per_machine = com.get_default_mpiprocs_per_machine()
- if not default_per_machine:
- default_per_machine = 24 # claix, lsf does can not have default mpiprocs... #TODO this better
- tot_num_mpiprocs = resources.get('tot_num_mpiprocs', default_per_machine * nnodes)
-
- if scheduler_type == 'lsf':
- new_resources = {'tot_num_mpiprocs': tot_num_mpiprocs} # only this needs to be given
- elif scheduler_type == 'torque':
- # {'num_machines', 1} # on iff003 currently we do not do multinode mpi,
- new_resources = resources
- # like this it will get stuck on iff003
- else:
- new_resources = resources
- scheduler_extras = extras.get(scheduler_type, '')
-
- return new_resources, scheduler_extras
-
-
-# test
-###############################
-# codename = 'inpgen@local_mac'#'inpgen_v0.28@iff003'#'inpgen_iff@local_iff'
-# codename2 = 'fleur_v0.28@iff003'#'fleur_mpi_v0.28@iff003'# 'fleur_iff_0.28@local_iff''
-# codename2 = 'fleur_max_1.3_dev@iff003'
-# codename2 = 'fleur_mpi_max_1.3_dev@iff003'
-# codename4 = 'fleur_mpi_v0.28@claix'
-###############################
-# code = Code.get_from_string(codename)
-# code2 = Code.get_from_string(codename2)
-# code4 = Code.get_from_string(codename4)
-# print(get_scheduler_extras(code, {'num_machines' : 1}))
-# print(get_scheduler_extras(code2, {'num_machines' : 2}))
-# print(get_scheduler_extras(code4, {'num_machines' : 1}))
-
-
def test_and_get_codenode(codenode, expected_code_type, use_exceptions=False):
"""
Pass a code node and an expected code (plugin) type. Check that the
@@ -280,7 +218,7 @@ def test_and_get_codenode(codenode, expected_code_type, use_exceptions=False):
code = codenode
if code.get_input_plugin_name() != expected_code_type:
raise ValueError
- except ValueError:
+ except ValueError as exc:
from aiida.orm.querybuilder import QueryBuilder
qb = QueryBuilder()
qb.append(Code, filters={'attributes.input_plugin': {'==': expected_code_type}}, project='*')
@@ -293,7 +231,7 @@ def test_and_get_codenode(codenode, expected_code_type, use_exceptions=False):
msg += '\n'.join('* {}'.format(l) for l in valid_code_labels)
if use_exceptions:
- raise ValueError(msg)
+ raise ValueError(msg) from exc
else:
print(msg) # , file=sys.stderr)
sys.exit(1)
@@ -302,7 +240,7 @@ def test_and_get_codenode(codenode, expected_code_type, use_exceptions=False):
'Configure at least one first using\n'
' verdi code setup'.format(expected_code_type))
if use_exceptions:
- raise ValueError(msg)
+ raise ValueError(msg) from exc
else:
print(msg) # , file=sys.stderr)
sys.exit(1)
@@ -353,6 +291,9 @@ def determine_favorable_reaction(reaction_list, workchain_dict):
workchain_dict = {'Be12W' : uuid_wc or output, 'Be2W' : uuid, ...}
return dictionary that ranks the reactions after their enthalpy
+
+ TODO: refactor aiida part out of this, leaving an aiida independent part and one
+ more universal
"""
from aiida.engine import WorkChain
from aiida_fleur.tools.common_fleur_wf_util import get_enhalpy_of_equation
@@ -384,7 +325,7 @@ def determine_favorable_reaction(reaction_list, workchain_dict):
except (AttributeError, KeyError, ValueError): # TODO: Check this
ouputnode = None
formenergy = None
- print(('WARNING: ouput node of {} not found. I skip'.format(n)))
+ print(('WARNING: output node of {} not found. I skip'.format(n)))
continue
formenergy = ouputnode.get('formation_energy')
# TODO is this value per atom?
@@ -401,28 +342,6 @@ def determine_favorable_reaction(reaction_list, workchain_dict):
return energy_sorted_reactions
-# test
-# reaction_list = ['1*Be12W->1*Be12W', '2*Be12W->1*Be2W+1*Be22W', '11*Be12W->5*W+6*Be22W', '1*Be12W->12*Be+1*W', '1*Be12W->1*Be2W+10*Be']
-# workchain_dict = {'Be12W' : '4f685bc5-b5fb-46d3-aad6-e0f512c3313d',
-# 'Be2W' : '045d3071-f442-46b4-8d6b-3c85d72b24d4',
-# 'Be22W' : '1e32880a-bdc9-4081-a5da-be04860aa1bc',
-# 'W' : 'f8b12b23-0b71-45a1-9040-b51ccf379439',
-# 'Be' : 0.0}
-# reac_list = determine_favorable_reaction(reaction_list, workchain_dict)
-# print reac_list
-# {'products': {'Be12W': 1}, 'educts': {'Be12W': 1}}
-# 0.0
-# {'products': {'Be2W': 1, 'Be22W': 1}, 'educts': {'Be12W': 2}}
-# 0.114321037514
-# {'products': {'Be22W': 6, 'W': 5}, 'educts': {'Be12W': 11}}
-# -0.868053153884
-# {'products': {'Be': 12, 'W': 1}, 'educts': {'Be12W': 1}}
-# -0.0946046496213
-# {'products': {'Be': 10, 'Be2W': 1}, 'educts': {'Be12W': 1}}
-# 0.180159355144
-# [['11*Be12W->5*W+6*Be22W', -0.8680531538839534], ['1*Be12W->12*Be+1*W', -0.0946046496213127], ['1*Be12W->1*Be12W', 0.0], ['2*Be12W->1*Be2W+1*Be22W', 0.11432103751404535], ['1*Be12W->1*Be2W+10*Be', 0.1801593551436103]]
-
-
def performance_extract_calcs(calcs):
"""
Extracts some runtime and system data from given fleur calculations
diff --git a/aiida_fleur/tools/common_fleur_wf_util.py b/aiida_fleur/tools/common_fleur_wf_util.py
index 4599728d9..54d9eb23c 100644
--- a/aiida_fleur/tools/common_fleur_wf_util.py
+++ b/aiida_fleur/tools/common_fleur_wf_util.py
@@ -568,13 +568,3 @@ def check_eos_energies(energylist):
print('annormly detected')
return abnormality, abnormalityindexlist
-
-
-#total_energy = [ -1, -2, -3 ,-2,-4,-3,-2,-1]
-#check_eos_energies(total_energy)
-#(True, [3])
-#total_energy = [ -1, -2, -3 ,-2,-2,-3,-2,-1]
-#check_eos_energies(total_energy)
-#(False, [])
-#total_energy = [ -1, -2, -3 ,-4,-5,-3,-2,-1]
-#(False, [])
diff --git a/aiida_fleur/tools/create_corehole.py b/aiida_fleur/tools/create_corehole.py
index b81cc5617..a9a94b347 100644
--- a/aiida_fleur/tools/create_corehole.py
+++ b/aiida_fleur/tools/create_corehole.py
@@ -13,48 +13,41 @@
Contains helper functions to create core-holes in
Fleur input files from AiiDA data nodes.
'''
-from __future__ import absolute_import
-from __future__ import print_function
-from aiida.plugins import DataFactory
-import six
+
# TODO maybe merge these methods into fleurinp or structure util? or create a parameterData utils
#355
-
-
def create_corehole_para(structure, kind, econfig, species_name='corehole', parameterdata=None):
"""
This methods sets of electron configurations for a kind
or position given, make sure to break the symmetry for this position/kind
beforehand, otherwise you will create several coreholes.
- param: structure: StructureData
- param: kind, a string with the kind_name (TODO: alternative the kind object)
- param: econfig, string, e.g. econfig = "[Kr] 5s2 4d10 4f13 | 5p6 5d5 6s2"
- ! THis is the new econfig therefore
+ :param structure: StructureData
+ :param kind: a string with the kind_name (TODO: alternative the kind object)
+ :param econfig: string, e.g. econfig = "[Kr] 5s2 4d10 4f13 | 5p6 5d5 6s2" to set, i.e. the corehole
- returns a Dict node
+ :return: a Dict node
"""
-
+ # TODO: Since fleur MaXR5 there is a default econfig file and the order behavior
+ # has changed. now to atom lists only change the default if they have an id.
from aiida.common.constants import elements as PeriodicTableElements
-
- _atomic_numbers = {data['symbol']: num for num, data in six.iteritems(PeriodicTableElements)}
+ from aiida import orm
+ _atomic_numbers = {data['symbol']: num for num, data in PeriodicTableElements.items()}
#from aiida_fleur.tools.merge_parameter import merge_parameter
kindo = structure.get_kind(kind)
symbol = kindo.symbol
head = kindo.name.rstrip('01223456789')
- #print(kindo)
charge = _atomic_numbers[kindo.symbol]
a_id = float('{}.{}'.format(charge, kindo.name[len(head):]))
- #print('a_id {}'.format(a_id))
# get kind symbol, get kind name,
#&atom element="W" jri=921 lmax=8 rmt=2.52 dx=0.014 lo="5p" econfig="[Kr] 5s2 4d10 4f13 | 5p6 5d4 6s2" /
#count = 0
if parameterdata:
new_parameterd = parameterdata.get_dict() # dict()otherwise parameterdata is changed
- for key, val in six.iteritems(new_parameterd):
+ for key, val in new_parameterd.items():
if 'atom' in key:
if val.get('element', None) == symbol:
# remember atomic id is atomic number.some int
@@ -74,13 +67,13 @@ def create_corehole_para(structure, kind, econfig, species_name='corehole', para
else:
new_parameterd = {'atom': {'element': symbol, 'econfig': econfig}}
- from aiida.orm import Dict
- new_parameter = Dict(dict=new_parameterd)
+ new_parameter = orm.Dict(dict=new_parameterd)
#if parameterdata:
# new_parameter = merge_parameter(parameterdata, new_parameter)
return new_parameter #structure
+'''
# Move to fleurinpmod? fleurinp->self
# This method is fully implemented yet since it turned out to better go over inpgen
def create_corehole_fleurinp(fleurinp, species, stateocc, pos=None, coreconfig='same', valenceconfig='same'):
@@ -110,14 +103,14 @@ def create_corehole_fleurinp(fleurinp, species, stateocc, pos=None, coreconfig='
:return: the changes fleurinpData object
"""
- '''
-
- [Kr] (5s1/2) (4d3/2) (4d5/2) (4f5/2) (4f7/2)
- (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
-
-
-
- '''
+
+ #
+ # [Kr] (5s1/2) (4d3/2) (4d5/2) (4f5/2) (4f7/2)
+ # (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
+ #
+ #
+ #
+
from aiida_fleur.tools.xml_util import eval_xpath2, get_xml_attribute
#from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
# or from fleurinp?
@@ -191,3 +184,4 @@ def write_change(xmltree, changelist_xpath):
xpath = element[0]
value = element[1]
return xmltree_new
+'''
diff --git a/aiida_fleur/tools/dict_util.py b/aiida_fleur/tools/dict_util.py
index 6fde96cd5..e8e7dcf37 100644
--- a/aiida_fleur/tools/dict_util.py
+++ b/aiida_fleur/tools/dict_util.py
@@ -81,6 +81,25 @@ def dict_merger(dict1, dict2):
return new_dict
+def clean_nones(dict_to_clean):
+ """Recursively remove all keys which values are None from a nested dictionary
+ return the cleaned dictionary
+
+ :param dict_to_clean: (dict): python dictionary to remove keys with None as value
+ :return: dict, cleaned dictionary
+ """
+ new_dict = {}
+ for key, val in dict_to_clean.items():
+ if isinstance(val, dict):
+ new_val = clean_nones(val)
+ else:
+ new_val = val
+ if new_val is not None: # currently we keep empty dicts
+ new_dict[key] = new_val
+
+ return new_dict
+
+
def recursive_merge(left: typ.Dict[str, typ.Any], right: typ.Dict[str, typ.Any]) -> typ.Dict[str, typ.Any]:
"""
Recursively merge two dictionaries into a single dictionary.
diff --git a/aiida_fleur/tools/merge_parameter.py b/aiida_fleur/tools/merge_parameter.py
index 8e6ce1001..6bebdcdd6 100644
--- a/aiida_fleur/tools/merge_parameter.py
+++ b/aiida_fleur/tools/merge_parameter.py
@@ -13,8 +13,6 @@
This module, contains a method to merge Dict nodes used by the FLEUR inpgen.
This might also be of interest for other all-electron codes
"""
-# TODO this should be made an inline calculation or calcfunction to
-# keep the proverance!
# Shall we allow for a python dictionary also instead of forcing paramteraData?
# but then we can not keep the provenace...
@@ -43,6 +41,8 @@ def merge_parameter(Dict1, Dict2, overwrite=True, merge=True):
:param merge: bool, default True
returns: AiiDA Dict Node
+
+ #TODO be more carefull how to merge ids in atom namelists, i.e species labels
"""
from aiida.common.exceptions import InputValidationError
@@ -65,6 +65,9 @@ def merge_parameter(Dict1, Dict2, overwrite=True, merge=True):
dict1 = Dict1.get_dict()
dict2 = Dict2.get_dict()
+ if dict1 == dict2:
+ return Dict(dict=dict1)
+
for key in list(dict1.keys()):
if 'atom' in key:
val = dict1.pop(key)
@@ -148,6 +151,8 @@ def merge_parameters_wf(*Dicts, overwrite=Bool(True)):
return paremeter_data_new
'''
+'''
+#TODO this has to moved into cmdline
if __name__ == '__main__':
import argparse
#Dict = DataFactory('dict')
@@ -162,3 +167,4 @@ def merge_parameters_wf(*Dicts, overwrite=Bool(True)):
required=False)
args = parser.parse_args()
merge_parameter(Dict1=args.para1, Dict2=args.para1, overwrite=args.overwrite)
+ '''
diff --git a/aiida_fleur/tools/read_cif_folder.py b/aiida_fleur/tools/read_cif_folder.py
index 6401eb8f8..d8104460e 100644
--- a/aiida_fleur/tools/read_cif_folder.py
+++ b/aiida_fleur/tools/read_cif_folder.py
@@ -49,6 +49,8 @@ def read_cif_folder(path=os.getcwd(),
:params: extras: dir/string/arb: extras added to the structures stored in the db
"""
+ # TODO check for duplicates in the database, so that reruning the functions
+ # won't import anything else in the database
cifdata = DataFactory('cif')
############ parameters for the user to set ########
@@ -104,7 +106,7 @@ def read_cif_folder(path=os.getcwd(),
# continue
#asecell = new_cif[0].get_ase()
#structuredatas.append(DataFactory('structure'))
- #filenames2.append(filenames[i])
+ filenames2.append(filenames[i])
#struc = structuredatas[-1](ase=asecell)
#formula = struc.get_formula()
if store_db:
@@ -119,7 +121,7 @@ def read_cif_folder(path=os.getcwd(),
user = struc.user # we are the creator
struc.add_comment(comment, user)
if extra:
- if isinstance(extra, type(dict())):
+ if isinstance(extra, dict):
struc.set_extra_many(extra)
else:
struc.set_extra('specification', extra)
@@ -127,7 +129,7 @@ def read_cif_folder(path=os.getcwd(),
structuredatas2.append(struc)
else:
struc = struc_from_cif(new_cif[0])
- structuredatas.append(struc)
+ structuredatas2.append(struc)
formula = struc.get_formula()
if write_log:
# This file is a logfile/info file created by 'read_cif_folder'
@@ -154,9 +156,7 @@ def read_cif_folder(path=os.getcwd(),
@cf
def wf_struc_from_cif(cif):
- asecell = cif.get_ase()
- struc = DataFactory('structure')(ase=asecell)
- return struc
+ return struc_from_cif(cif)
def struc_from_cif(cif):
@@ -165,6 +165,9 @@ def struc_from_cif(cif):
return struc
+# TODO add this to command line, or better move to aiida-jutools
+# ggf add what Roman has done there.
+'''
if __name__ == '__main__':
import argparse
import json
@@ -212,3 +215,4 @@ def struc_from_cif(cif):
read_cif_folder(path=args.p, recursive=args.r, store=args.s, log=args.l, comments=args.c, extras=args.e)
else:
read_cif_folder(recursive=args.r, store=args.s, log=args.l, comments=args.c, extras=args.e)
+'''
diff --git a/aiida_fleur/tools/xml_util.py b/aiida_fleur/tools/xml_util.py
index 994302770..1c54d8ed5 100644
--- a/aiida_fleur/tools/xml_util.py
+++ b/aiida_fleur/tools/xml_util.py
@@ -110,13 +110,15 @@ def convert_htr_to_ev(value, parser_info_out=None):
"""
Multiplies the value given with the Hartree factor (converts htr to eV)
"""
+ from aiida_fleur.common.constants import HTR_TO_EV
+ # htr = 27.21138602
if parser_info_out is None:
parser_info_out = {'parser_warnings': []}
- htr = 27.21138602
+
suc = False
value_to_save, suc = convert_to_float(value, parser_info_out=parser_info_out)
if suc:
- return value_to_save * htr
+ return value_to_save * HTR_TO_EV
else:
return value
@@ -125,13 +127,14 @@ def convert_ev_to_htr(value, parser_info_out=None):
"""
Divides the value given with the Hartree factor (converts htr to eV)
"""
+ from aiida_fleur.common.constants import HTR_TO_EV
+ # htr = 27.21138602
if parser_info_out is None:
parser_info_out = {'parser_warnings': []}
- htr = 27.21138602
suc = False
value_to_save, suc = convert_to_float(value, parser_info_out=parser_info_out)
if suc:
- return value_to_save / htr
+ return value_to_save / HTR_TO_EV
else:
return value
@@ -413,7 +416,8 @@ def create_tag(xmlnode, xpath, newelement, create=False, place_index=None, tag_o
try:
newelement = etree.Element(newelement)
except ValueError as v:
- raise ValueError('{}. If this is a species, are you sure this species exists ' 'in your inp.xml?'.format(v))
+ raise ValueError('{}. If this is a species, are you sure this species exists '
+ 'in your inp.xml?'.format(v)) from v
nodes = eval_xpath3(xmlnode, xpath, create=create)
if nodes:
for node_1 in nodes:
@@ -423,8 +427,8 @@ def create_tag(xmlnode, xpath, newelement, create=False, place_index=None, tag_o
# behind what shall I place it
try:
place_index = tag_order.index(newelement_name)
- except:
- raise ValueError('Did not find element name in the tag_order list')
+ except ValueError as exc:
+ raise ValueError('Did not find element name in the tag_order list') from exc
behind_tags = tag_order[:place_index]
# check if children are in the same sequence as given in tag_order
tags = []
@@ -435,8 +439,9 @@ def create_tag(xmlnode, xpath, newelement, create=False, place_index=None, tag_o
for name in tags:
try:
current = tag_order.index(name)
- except ValueError:
- raise ValueError('Did not find existing tag name in the tag_order list' ': {}'.format(name))
+ except ValueError as exc:
+ raise ValueError('Did not find existing tag name in the tag_order list'
+ ': {}'.format(name)) from exc
if current > prev:
prev = current
else:
@@ -449,10 +454,10 @@ def create_tag(xmlnode, xpath, newelement, create=False, place_index=None, tag_o
tag_index = node_1.index(child)
try:
node_1.insert(tag_index + 1, element_to_write)
- except ValueError as v:
+ except ValueError as exc:
raise ValueError('{}. If this is a species, are'
'you sure this species exists in your inp.xml?'
- ''.format(v))
+ ''.format(exc)) from exc
was_set = True
break
if was_set:
@@ -460,23 +465,23 @@ def create_tag(xmlnode, xpath, newelement, create=False, place_index=None, tag_o
if not was_set: # just append
try:
node_1.insert(0, element_to_write)
- except ValueError as v:
+ except ValueError as exc:
raise ValueError('{}. If this is a species, are you'
' sure this species exists in your inp.xml?'
- ''.format(v))
+ ''.format(exc)) from exc
# (or remove all and write them again in right order?)
else:
try:
node_1.insert(place_index, element_to_write)
- except ValueError as v:
+ except ValueError as exc:
raise ValueError('{}. If this is a species, are you sure this species '
- 'exists in your inp.xml?'.format(v))
+ 'exists in your inp.xml?'.format(exc)) from exc
else:
try:
node_1.append(element_to_write)
- except ValueError as v:
+ except ValueError as exc:
raise ValueError('{}. If this is a species, are you sure this species exists'
- 'in your inp.xml?'.format(v))
+ 'in your inp.xml?'.format(exc)) from exc
return xmlnode
@@ -551,12 +556,14 @@ def get_inpgen_paranode_from_xml(inpxmlfile):
return Dict(dict=para_dict)
-def get_inpgen_para_from_xml(inpxmlfile):
+def get_inpgen_para_from_xml(inpxmlfile, inpgen_ready=True):
"""
This routine returns an python dictionary produced from the inp.xml
file, which can be used as a calc_parameters node by inpgen.
Be aware that inpgen does not take all information that is contained in an inp.xml file
+ :param inpxmlfile: and xml etree of a inp.xml file
+ :param inpgen_ready: Bool, return a dict which can be inputed into inpgen while setting atoms
:return new_parameters: A Dict, which will lead to the same inp.xml (in case if other defaults,
which can not be controlled by input for inpgen, were changed)
@@ -583,7 +590,7 @@ def get_inpgen_para_from_xml(inpxmlfile):
atom_jri_xpath = 'mtSphere/@gridPoints'
atom_lmax_xpath = 'atomicCutoffs/@lmax'
atom_lnosph_xpath = 'atomicCutoffs/@lnonsphr'
- atom_ncst_xpath = '@coreStates'
+ #atom_ncst_xpath = '@coreStates'
atom_econfig_xpath = 'electronConfig' # converting todo
atom_bmu_xpath = '@magMom'
atom_lo_xpath = 'lo' # converting todo
@@ -651,26 +658,28 @@ def get_inpgen_para_from_xml(inpxmlfile):
atom_jri = convert_to_int(eval_xpath(species, atom_jri_xpath), suc_return=False)
atom_lmax = convert_to_int(eval_xpath(species, atom_lmax_xpath), suc_return=False)
atom_lnosph = convert_to_int(eval_xpath(species, atom_lnosph_xpath), suc_return=False)
- atom_ncst = convert_to_int(eval_xpath(species, atom_ncst_xpath), suc_return=False)
+ #atom_ncst = convert_to_int(eval_xpath(species, atom_ncst_xpath), suc_return=False)
atom_econfig = eval_xpath(species, atom_econfig_xpath)
atom_bmu = convert_to_float(eval_xpath(species, atom_bmu_xpath), suc_return=False)
atom_lo = eval_xpath(species, atom_lo_xpath)
atom_element = eval_xpath(species, atom_element_xpath)
atom_name_2 = eval_xpath(species, atom_name_xpath)
- atom_dict = set_dict_or_not(atom_dict, 'z', atom_z)
+ if not inpgen_ready:
+ atom_dict = set_dict_or_not(atom_dict, 'z', atom_z)
+ #atom_dict = set_dict_or_not(atom_dict, 'name', atom_name_2)
+ #atom_dict = set_dict_or_not(atom_dict, 'ncst', atom_ncst) (deprecated)
atom_dict = set_dict_or_not(atom_dict, 'rmt', atom_rmt)
atom_dict = set_dict_or_not(atom_dict, 'dx', atom_dx)
atom_dict = set_dict_or_not(atom_dict, 'jri', atom_jri)
atom_dict = set_dict_or_not(atom_dict, 'lmax', atom_lmax)
atom_dict = set_dict_or_not(atom_dict, 'lnonsph', atom_lnosph)
- atom_dict = set_dict_or_not(atom_dict, 'ncst', atom_ncst)
+
atom_dict = set_dict_or_not(atom_dict, 'econfig', atom_econfig)
atom_dict = set_dict_or_not(atom_dict, 'bmu', atom_bmu)
if atom_lo is not None:
atom_dict = set_dict_or_not(atom_dict, 'lo', convert_fleur_lo(atom_lo))
atom_dict = set_dict_or_not(atom_dict, 'element', '{}'.format(atom_element))
- #atom_dict = set_dict_or_not(atom_dict, 'name', atom_name_2)
new_parameters[atoms_name] = atom_dict
@@ -1471,11 +1480,11 @@ def eval_xpath3(node, xpath, create=False, place_index=None, tag_order=None):
"""
try:
return_value = node.xpath(xpath)
- except etree.XPathEvalError:
+ except etree.XPathEvalError as exc:
message = ('There was a XpathEvalError on the xpath: {} \n Either it does '
'not exist, or something is wrong with the expression.'
''.format(xpath))
- raise etree.XPathEvalError(message)
+ raise etree.XPathEvalError(message) from exc
if return_value == []:
if create:
diff --git a/aiida_fleur/workflows/b_corehole.py.legacy b/aiida_fleur/workflows/b_corehole.py.legacy
deleted file mode 100644
index 2171cc0b0..000000000
--- a/aiida_fleur/workflows/b_corehole.py.legacy
+++ /dev/null
@@ -1,276 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-"""
-This is the worklfow 'corehole' using the Fleur code, which calculates Binding
-energies and corelevel shifts with different methods.
-'divide and conquer'
-"""
-# TODO alow certain kpoint path, or kpoint node, so far auto
-from __future__ import absolute_import
-from __future__ import print_function
-from aiida_fleur.data.fleurinp import FleurinpData
-from aiida import load_dbenv, is_dbenv_loaded
-import six
-if not is_dbenv_loaded():
- load_dbenv()
-
-import os.path
-from aiida.plugins import Code, DataFactory
-from aiida.engine import WorkChain
-from aiida.engine import submit
-from aiida.engine import ToContext
-from aiida.engine.process_registry import ProcessRegistry
-
-from aiida_fleur.calculation.fleur import FleurCalculation
-from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
-from aiida.engine import while_, if_
-from aiida_fleur.tools.create_corehole import create_corehole
-
-StructureData = DataFactory('structure')
-Dict = DataFactory('dict')
-RemoteData = DataFactory('remote')
-FleurProcess = FleurCalculation.process()
-
-
-class fleur_corehole_wc(WorkChain):
- '''
- Turn key solution for the calculation of core level shift and Binding energies
-
-
- '''
- # wf_Parameters: Dict,
- '''
- 'method' : ['initial', 'full_valence ch', 'half_valence_ch', 'ch', ...]
- 'Bes' : [W4f, Be1s]
- 'CLS' : [W4f, Be1s]
- 'atoms' : ['all', 'postions' : []]
- 'references' : ['calculate', or
- 'scf_para' : {...}, 'default'
- 'relax' : True
- 'relax_mode': ['Fleur', 'QE Fleur', 'QE']
- 'relax_para' : {...}, 'default'
- 'calculate_doses' : False
- 'dos_para' : {...}, 'default'
- '''
- '''
- # defaults
- default wf_Parameters::
- 'method' : 'initial'
- 'atoms' : 'all
- 'references' : 'calculate'
- 'scf_para' : 'default'
- 'relax' : True
- 'relax_mode': 'QE Fleur'
- 'relax_para' : 'default'
- 'calculate_doses' : False
- 'dos_para' : 'default'
- '''
-
- _workflowversion = "0.0.1"
-
- @classmethod
- def define(cls, spec):
- super(fleur_corehole_wc, cls).define(spec)
- spec.input("wf_parameters", valid_type=Dict, required=False,
- default=Dict(dict={
- 'method' : 'initial',
- 'atoms' : 'all',
- 'references' : 'calculate',
- 'relax' : False,
- 'relax_mode': 'Fleur',
- 'relax_para' : 'default',
- 'scf_para' : 'default',
- }))
- spec.input("fleurinp", valid_type=FleurinpData, required=True)
- spec.input("fleur", valid_type=Code, required=True)
- spec.input("structure", valid_type=StructureData, required=False)
- spec.input("calc_parameters", valid_type=Dict, required=False)
- spec.outline(
- cls.check_input,
- if_(cls.relaxation_needed)(
- cls.relax),
- if_(cls.supercell_needed)(
- cls.create_supercell
- ),
- cls.create_new_fleurinp,
- cls.create_coreholes,
- cls.run_scfs,
- cls.collect_results,
- cls.return_results
- )
- #spec.dynamic_output()
-
-
- def check_input(self):
- '''
- check parameters, what condictions? complete?
- check input nodes
- '''
- ### input check ### ? or done automaticly, how optional?
- # check if fleuinp corresponds to fleur_calc
- print(('started bands workflow version {}'.format(self._workflowversion)))
- print(("Workchain node identifiers: {}"
- "".format(ProcessRegistry().current_calc_node)))
-
- def relaxation_needed(self):
- """
- If the structures should be relaxed, check if their Forces are below a certain
- threshold, otherwise throw them in the relaxation wf.
- """
- print('In relaxation inital_state_CLS workflow')
- if self.ctx.relax:
- # TODO check all forces of calculations
- forces_fine = True
- if forces_fine:
- return True
- else:
- return False
- else:
- return False
-
-
- def relax(self):
- """
- Do structural relaxation for certain structures.
- """
- print('In relax inital_state_CLS workflow')
- for calc in self.ctx.dos_to_calc:
- pass
- # TODO run relax workflow
-
- def create_new_fleurinp(self):
- """
- create a new fleurinp from the old with certain parameters
- """
- # TODO allow change of kpoint mesh?, tria?
- wf_dict = self.inputs.wf_parameters.get_dict()
- nkpts = wf_dict.get('nkpts', 500)
- # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0
- sigma = wf_dict.get('sigma', 0.005)
- emin = wf_dict.get('emin', -0.30)
- emax = wf_dict.get('emax', 0.80)
-
- fleurmode = FleurinpModifier(self.inputs.fleurinp)
-
- #change_dict = {'band': True, 'ndir' : -1, 'minEnergy' : self.inputs.wf_parameters.get_dict().get('minEnergy', -0.30000000),
- #'maxEnergy' : self.inputs.wf_parameters.get_dict().get('manEnergy','0.80000000'),
- #'sigma' : self.inputs.wf_parameters.get_dict().get('sigma', '0.00500000')}
- change_dict = {'band': True, 'ndir' : 0, 'minEnergy' : emin,
- 'maxEnergy' : emax, 'sigma' : sigma} #'ndir' : 1, 'pot8' : True
-
- fleurmode.set_inpchanges(change_dict)
-
- if nkpts:
- fleurmode.set_nkpts(count=nkpts)
- #fleurinp_new.replace_tag()
-
- fleurmode.show(validate=True, display=False) # needed?
- fleurinp_new = fleurmode.freeze()
- self.ctx.fleurinp1 = fleurinp_new
- print(fleurinp_new)
- #print(fleurinp_new.folder.get_subfolder('path').get_abs_path(''))
-
- def get_inputs_fleur(self):
- '''
- get the input for a FLEUR calc
- '''
- inputs = FleurProcess.get_inputs_template()
-
- fleurin = self.ctx.fleurinp1
- #print fleurin
- remote = self.inputs.remote
- inputs.parent_folder = remote
- inputs.code = self.inputs.fleur
- inputs.fleurinpdata = fleurin
-
- # TODO nkpoints decide n core
-
- core = 12 # get from computer nodes per machine
- inputs._options.resources = {"num_machines": 1, "num_mpiprocs_per_machine" : core}
- inputs._options.max_wallclock_seconds = 30 * 60
-
- if self.ctx.serial:
- inputs._options.withmpi = False # for now
- inputs._options.resources = {"num_machines": 1}
-
- if self.ctx.queue:
- inputs._options.queue_name = self.ctx.queue
- print(self.ctx.queue)
- # if code local use
- #if self.inputs.fleur.is_local():
- # inputs._options.computer = computer
- # #else use computer from code.
- #else:
- # inputs._options.queue_name = 'th1'
-
- if self.ctx.serial:
- inputs._options.withmpi = False # for now
- inputs._options.resources = {"num_machines": 1}
-
- return inputs
-
- def run_fleur(self):
- '''
- run a fleur calculation
- '''
- FleurProcess = FleurCalculation.process()
- inputs = {}
- inputs = self.get_inputs_fleur()
- #print inputs
- future = submit(FleurProcess, **inputs)
- print('run Fleur in band workflow')
-
- return ToContext(last_calc=future)
-
- def return_results(self):
- '''
- return the results of the calculations
- '''
- # TODO more here
- print('Band workflow Done')
- print(('A bandstructure was calculated for fleurinpdata {} and is found under pk={}, '
- 'calculation {}'.format(self.inputs.fleurinp, self.ctx.last_calc.pk, self.ctx.last_calc)))
-
- #check if band file exists: if not succesful = False
- #TODO be careful with general bands.X
-
- bandfilename = 'bands.1' # ['bands.1', 'bands.2', ...]
- # TODO this should be easier...
- last_calc_retrieved = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path')
- bandfilepath = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path(bandfilename)
- print(bandfilepath)
- #bandfilepath = "path to bandfile" # Array?
- if os.path.isfile(bandfilepath):
- self.ctx.successful = True
- else:
- bandfilepath = None
- print('!NO bandstructure file was found, something went wrong!')
- #TODO corret efermi:
- # get efermi from last calculation
- efermi1 = self.inputs.remote.get_inputs()[-1].res.fermi_energy
- #get efermi from this caclulation
- efermi2 = self.ctx.last_calc.res.fermi_energy
- diff_efermi = efermi1 - efermi2
- # store difference in output node
- # adjust difference in band.gnu
- #filename = 'gnutest2'
-
- outputnode_dict ={}
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['Warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['diff_efermi'] = diff_efermi
- #outputnode_dict['last_calc_pk'] = self.ctx.last_calc.pk
- #outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['bandfile'] = bandfilepath
- outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['last_calc_retrieved'] = last_calc_retrieved
- #print outputnode_dict
- outputnode = Dict(dict=outputnode_dict)
- outdict = {}
- outdict['output_corehole_wc_para'] = outputnode
- #print outdict
- for k, v in six.iteritems(outdict):
- self.out(k, v)
diff --git a/aiida_fleur/workflows/band.py b/aiida_fleur/workflows/band.py
deleted file mode 100644
index 98733db44..000000000
--- a/aiida_fleur/workflows/band.py
+++ /dev/null
@@ -1,346 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-"""
-This is the worklfow 'band' for the Fleur code, which calculates a
-electron bandstructure.
-"""
-# TODO alow certain kpoint path, or kpoint node, so far auto
-# TODO alternative parse a structure and run scf
-from __future__ import absolute_import
-from __future__ import print_function
-import os.path
-import copy
-import six
-
-from aiida.plugins import DataFactory
-from aiida.orm import Code, StructureData, Dict, RemoteData
-from aiida.engine import WorkChain, ToContext, if_
-from aiida.engine import calcfunction as cf
-from aiida.common.exceptions import NotExistent
-from aiida.common import AttributeDict
-
-from aiida_fleur.workflows.scf import FleurScfWorkChain
-from aiida_fleur.workflows.base_fleur import FleurBaseWorkChain
-from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
-from aiida_fleur.tools.common_fleur_wf import get_inputs_fleur
-from aiida_fleur.tools.common_fleur_wf import test_and_get_codenode, is_code
-from aiida_fleur.data.fleurinp import FleurinpData
-
-
-class FleurBandWorkChain(WorkChain):
- '''
- This workflow calculated a bandstructure from a Fleur calculation
-
- :Params: a Fleurcalculation node
- :returns: Success, last result node, list with convergence behavior
- '''
- # wf_parameters: { 'tria', 'nkpts', 'sigma', 'emin', 'emax'}
- # defaults : tria = True, nkpts = 800, sigma=0.005, emin= , emax =
-
- _workflowversion = '0.3.4'
-
- _default_options = {
- 'resources': {
- 'num_machines': 1,
- 'num_mpiprocs_per_machine': 1
- },
- 'max_wallclock_seconds': 60 * 60,
- 'queue_name': '',
- 'custom_scheduler_commands': '',
- 'import_sys_environment': False,
- 'environment_variables': {}
- }
- _wf_default = {
- 'fleur_runmax': 4,
- 'kpath': 'auto',
- # 'nkpts' : 800,
- 'sigma': 0.005,
- 'emin': -0.50,
- 'emax': 0.90
- }
-
- @classmethod
- def define(cls, spec):
- super(FleurBandWorkChain, cls).define(spec)
- # spec.expose_inputs(FleurScfWorkChain, namespace='scf')
- spec.input('wf_parameters', valid_type=Dict, required=False)
- spec.input('fleur', valid_type=Code, required=True)
- spec.input('remote', valid_type=RemoteData, required=False)
- spec.input('fleurinp', valid_type=FleurinpData, required=False)
- spec.input('options', valid_type=Dict, required=False)
-
- spec.outline(
- cls.start,
- if_(cls.scf_needed)(
- cls.converge_scf,
- cls.create_new_fleurinp,
- cls.run_fleur,
- ).else_(
- cls.create_new_fleurinp,
- cls.run_fleur,
- ), cls.return_results)
-
- spec.output('output_band_wc_para', valid_type=Dict)
-
- spec.exit_code(233,
- 'ERROR_INVALID_CODE_PROVIDED',
- message='Invalid code node specified, check inpgen and fleur code nodes.')
- spec.exit_code(231, 'ERROR_INVALID_INPUT_CONFIG', message='Invalid input configuration.')
-
- def start(self):
- '''
- check parameters, what condictions? complete?
- check input nodes
- '''
- ### input check ### ? or done automaticly, how optional?
- # check if fleuinp corresponds to fleur_calc
- self.report('started bands workflow version {}'.format(self._workflowversion))
- #print("Workchain node identifiers: ")#'{}'
- #"".format(ProcessRegistry().current_calc_node))
-
- self.ctx.fleurinp_band = ''
- self.ctx.last_calc = None
- self.ctx.successful = False
- self.ctx.info = []
- self.ctx.warnings = []
- self.ctx.errors = []
- self.ctx.calcs = []
-
- inputs = self.inputs
-
- wf_default = copy.deepcopy(self._wf_default)
- if 'wf_parameters' in inputs:
- wf_dict = inputs.wf_parameters.get_dict()
- else:
- wf_dict = wf_default
-
- for key, val in six.iteritems(wf_default):
- wf_dict[key] = wf_dict.get(key, val)
- self.ctx.wf_dict = wf_dict
- # if MPI in code name, execute parallel
- self.ctx.serial = self.ctx.wf_dict.get('serial', False)
-
- defaultoptions = self._default_options
- if 'options' in inputs:
- options = inputs.options.get_dict()
- else:
- options = defaultoptions
-
- # extend options given by user using defaults
- for key, val in six.iteritems(defaultoptions):
- options[key] = options.get(key, val)
- self.ctx.options = options
-
- # set values, or defaults
- self.ctx.max_number_runs = self.ctx.wf_dict.get('fleur_runmax', 4)
-
- # Check if user gave valid fleur executable
- # if 'fleur' in inputs.scf:
- # try:
- # test_and_get_codenode(inputs.scf.fleur, 'fleur.fleur', use_exceptions=True)
- # except ValueError:
- # error = ("The code you provided for FLEUR does not use the plugin fleur.fleur")
- # self.control_end_wc(error)
- # return self.exit_codes.ERROR_INVALID_CODE_PROVIDED
-
- if 'scf' in inputs:
- self.ctx.scf_needed = True
- if 'remote' in inputs:
- error = 'ERROR: you gave SCF input + remote for the FT'
- self.control_end_wc(error)
- return self.exit_codes.ERROR_INVALID_INPUT_CONFIG
- elif 'remote' not in inputs:
- error = 'ERROR: you gave neither SCF input nor remote for the FT'
- self.control_end_wc(error)
- return self.exit_codes.ERROR_INVALID_INPUT_CONFIG
- else:
- self.ctx.scf_needed = False
-
- def create_new_fleurinp(self):
- """
- create a new fleurinp from the old with certain parameters
- """
- # TODO allow change of kpoint mesh?, tria?
- wf_dict = self.ctx.wf_dict
- # nkpts = wf_dict.get('nkpts', 500)
- # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0
- sigma = wf_dict.get('sigma', 0.005)
- emin = wf_dict.get('emin', -0.30)
- emax = wf_dict.get('emax', 0.80)
-
- fleurmode = FleurinpModifier(self.inputs.fleurinp)
-
- change_dict = {'band': True, 'ndir': 0, 'minEnergy': emin, 'maxEnergy': emax, 'sigma': sigma} #'ndir' : 1,
-
- fleurmode.set_inpchanges(change_dict)
-
- # if nkpts:
- # fleurmode.set_nkpts(count=nkpts)
- #fleurinp_new.replace_tag()
-
- fleurmode.show(validate=True, display=False) # needed?
- fleurinp_new = fleurmode.freeze()
- self.ctx.fleurinp_band = fleurinp_new
-
- def scf_needed(self):
- """
- Returns True if SCF WC is needed.
- """
- return self.ctx.scf_needed
-
- def converge_scf(self):
- """
- Converge charge density.
- """
- return 0
-
- def run_fleur(self):
- """
- run a FLEUR calculation
- """
- self.report('INFO: run FLEUR')
- # inputs = self.get_inputs_scf()
- fleurin = self.ctx.fleurinp_band
- remote = self.inputs.remote
- code = self.inputs.fleur
- options = self.ctx.options.copy()
- label = 'bansdtructure_calculation'
- description = 'Bandstructure is calculated for the given structure'
-
- inputs = get_inputs_fleur(code, remote, fleurin, options, label, description, serial=self.ctx.serial)
- future = self.submit(FleurBaseWorkChain, **inputs)
- self.ctx.calcs.append(future)
-
- return ToContext(last_calc=future)
-
- def get_inputs_scf(self):
- """
- Initialize inputs for scf workflow:
- wf_param, options, calculation parameters, codes, structure
- """
- input_scf = AttributeDict(self.exposed_inputs(FleurScfWorkChain, namespace='scf'))
- input_scf.fleurinp = self.ctx.fleurinp_band
-
- return input_scf
-
- def return_results(self):
- '''
- return the results of the calculations
- '''
- # TODO more here
- self.report('Band workflow Done')
- self.report('A bandstructure was calculated for fleurinpdata {} and is found under pk={}, '
- 'calculation {}'.format(self.inputs.fleurinp, self.ctx.last_calc.pk, self.ctx.last_calc))
-
- from aiida_fleur.tools.common_fleur_wf import find_last_submitted_calcjob
- if self.ctx.last_calc:
- try:
- last_calc_uuid = find_last_submitted_calcjob(self.ctx.last_calc)
- except NotExistent:
- last_calc_uuid = None
- else:
- last_calc_uuid = None
-
- try: # if something failed, we still might be able to retrieve something
- last_calc_out = self.ctx.last_calc.outputs.output_parameters
- retrieved = self.ctx.last_calc.outputs.retrieved
- last_calc_out_dict = last_calc_out.get_dict()
- except (NotExistent, AttributeError):
- last_calc_out = None
- last_calc_out_dict = {}
- retrieved = None
-
- #check if band file exists: if not succesful = False
- #TODO be careful with general bands.X
- # bandfilename = 'bands.1' # ['bands.1', 'bands.2', ...]
-
- # last_calc_retrieved = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path('')
- # bandfilepath = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path(bandfilename)
- # print(bandfilepath)
- # #bandfilepath = "path to bandfile" # Array?
- # if os.path.isfile(bandfilepath):
- # self.ctx.successful = True
- # else:
- # bandfilepath = None
- # self.report('!NO bandstructure file was found, something went wrong!')
-
- # #TODO corret efermi:
- # # get efermi from last calculation
- scf_results = self.inputs.remote_data.get_incoming().all()[-1].node.res
- efermi_scf = scf_results.fermi_energy
- bandgap_scf = scf_results.bandgap
- # efermi_band = last_calc_out_dict['fermi_energy']
- # bandgap_band = last_calc_out_dict['bandgap']
-
- # diff_efermi = efermi_scf - efermi_band
- # diff_bandgap = bandgap_scf - bandgap_band
-
- outputnode_dict = {}
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['Warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- # outputnode_dict['last_calc_uuid'] = last_calc_uuid
- # outputnode_dict['last_calc_pk'] = self.ctx.last_calc.pk
- # outputnode_dict['remote_dir'] = self.ctx.last_calc.get_remote_workdir()
- # outputnode_dict['fermi_energy_band'] = efermi_band
- # outputnode_dict['bandgap_band'] = bandgap_band
- outputnode_dict['fermi_energy_scf'] = efermi_scf
- outputnode_dict['bandgap_scf'] = bandgap_scf
- # outputnode_dict['diff_efermi'] = diff_efermi
- # outputnode_dict['diff_bandgap'] = diff_bandgap
-
- # outputnode_dict['diff_efermi'] = diff_efermi
- # outputnode_dict['bandfile'] = bandfilepath
-
- outputnode_t = Dict(dict=outputnode_dict)
- if last_calc_out:
- outdict = create_band_result_node(outpara=outputnode_t,
- last_calc_out=last_calc_out,
- last_calc_retrieved=retrieved)
- else:
- outdict = create_band_result_node(outpara=outputnode_t)
-
- #TODO parse Bandstructure
- for link_name, node in six.iteritems(outdict):
- self.out(link_name, node)
-
- def control_end_wc(self, errormsg):
- """
- Controlled way to shutdown the workchain. will initialize the output nodes
- The shutdown of the workchain will has to be done afterwards
- """
- self.report(errormsg) # because return_results still fails somewhen
- self.ctx.errors.append(errormsg)
- self.return_results()
-
-
-@cf
-def create_band_result_node(**kwargs):
- """
- This is a pseudo wf, to create the right graph structure of AiiDA.
- This wokfunction will create the output node in the database.
- It also connects the output_node to all nodes the information commes from.
- So far it is just also parsed in as argument, because so far we are to lazy
- to put most of the code overworked from return_results in here.
- """
- for key, val in six.iteritems(kwargs):
- if key == 'outpara': # should be always there
- outpara = val
- outdict = {}
- outputnode = outpara.clone()
- outputnode.label = 'output_band_wc_para'
- outputnode.description = ('Contains band calculation results')
-
- outdict['output_band_wc_para'] = outputnode
-
- return outdict
diff --git a/aiida_fleur/workflows/band2.py.legacy b/aiida_fleur/workflows/band2.py.legacy
deleted file mode 100644
index b50d92b51..000000000
--- a/aiida_fleur/workflows/band2.py.legacy
+++ /dev/null
@@ -1,270 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-
-
-"""
-This is the worklfow 'band2' for the Fleur code, which calculates a
-electron bandstructure from a given structure data node with seekpath.
-
-"""
-# TODO alow certain kpoint path, or kpoint node, so far auto
-# TODO alternative parse a structure and run scf
-from __future__ import absolute_import
-from __future__ import print_function
-import os.path
-from aiida.plugins import Code, DataFactory
-#from aiida.tools.codespecific.fleur.queue_defaults import queue_defaults
-from aiida.engine import WorkChain
-from aiida.engine import submit
-from aiida.engine import if_
-from aiida.engine import ToContext
-from aiida.engine import workfunction as wf
-#from aiida.work.process_registry import ProcessRegistry
-from aiida_fleur.calculation.fleur import FleurCalculation
-from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
-from aiida_fleur.tools.common_fleur_wf import get_inputs_fleur
-from seekpath.aiidawrappers import get_path, get_explicit_k_path
-import six
-
-StructureData = DataFactory('structure')
-Dict = DataFactory('dict')
-RemoteData = DataFactory('remote')
-KpointsData = DataFactory('array.kpoints')
-FleurinpData = DataFactory('fleur.fleurinp')
-FleurProcess = FleurCalculation.process()
-
-'''
-We want to run fleur with a certain kpath, which we will get from the seek path method
-'''
-
-
-class fleur_band2_wc(WorkChain):
- '''
- This workflow calculated a bandstructure from a Fleur calculation
-
- :Params: a Fleurcalculation node
- :returns:
- '''
-
- _workflowversion = "0.1.0"
-
- @classmethod
- def define(cls, spec):
- super(fleur_band2_wc, cls).define(spec)
- spec.input("wf_parameters", valid_type=Dict, required=False,
- default=Dict(dict={
- 'kpath' : 'auto',
- 'nkpts' : 800,
- 'sigma' : 0.005,
- 'emin' : -0.50,
- 'emax' : 0.90}))
-
- spec.input("fleur", valid_type=Code, required=True)
- spec.input("structure", valid_type=StructureData, required=False)
- spec.input("calc_parameters", valid_type=Dict, required=False)
- spec.input("settings", valid_type=Dict, required=False)
- spec.input("inpgen", valid_type=Code, required=False)
- spec.outline(
- cls.start,
- cls.setup_structure,
- cls.setup_kpoints,
- cls.setup_parameters,
- cls.create_new_fleurinp,
- cls.run_fleur,
- cls.return_results
- )
- #spec.dynamic_output()
-
-
- def start(self):
- '''
- check parameters, what condictions? complete?
- check input nodes
- '''
- ### input check ### ? or done automaticly, how optional?
- # check if fleuinp corresponds to fleur_calc
- print(('started bands workflow version {}'.format(self._workflowversion)))
- print("Workchain node identifiers: ")#{}"
- #"".format(ProcessRegistry().current_calc_node))
-
- self.ctx.fleurinp1 = ""
- self.ctx.last_calc = None
- self.ctx.successful = False
- self.ctx.warnings = []
-
- wf_dict = self.inputs.wf_parameters.get_dict()
-
- # if MPI in code name, execute parallel
- self.ctx.serial = wf_dict.get('serial', False)
-
- # set values, or defaults
- self.ctx.max_number_runs = wf_dict.get('fleur_runmax', 4)
- self.ctx.resources = wf_dict.get('resources', {"num_machines": 1})
- self.ctx.walltime_sec = wf_dict.get('walltime_sec', 10*30)
- self.ctx.queue = wf_dict.get('queue_name', None)
-
-
-
- def setup_structure(self):
- """
- We use SeeKPath to determine the primitive structure for the given input structure, if it
- wasn't yet the case.
- """
- seekpath_result = seekpath_structure(self.inputs.structure)
- self.ctx.structure_initial_primitive = seekpath_result['primitive_structure']
-
- def setup_kpoints(self):
- """
- Define the k-point mesh for the relax and scf calculations. Also get the k-point path for
- the bands calculation for the initial input structure from SeeKpath
- """
- kpoints_mesh = KpointsData()
- kpoints_mesh.set_cell_from_structure(self.inputs.structure)
- kpoints_mesh.set_kpoints_mesh_from_density(
- distance=self.ctx.protocol['kpoints_mesh_density'],
- offset=self.ctx.protocol['kpoints_mesh_offset']
- )
-
- self.ctx.kpoints_mesh = kpoints_mesh
-
-
- def create_new_fleurinp(self):
- """
- create a new fleurinp from the old with certain parameters
- """
- # TODO allow change of kpoint mesh?, tria?
- wf_dict = self.inputs.wf_parameters.get_dict()
- nkpts = wf_dict.get('nkpts', 500)
- # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0
- sigma = wf_dict.get('sigma', 0.005)
- emin = wf_dict.get('emin', -0.30)
- emax = wf_dict.get('emax', 0.80)
-
- fleurmode = FleurinpModifier(self.inputs.fleurinp)
-
- #change_dict = {'band': True, 'ndir' : -1, 'minEnergy' : self.inputs.wf_parameters.get_dict().get('minEnergy', -0.30000000),
- #'maxEnergy' : self.inputs.wf_parameters.get_dict().get('manEnergy','0.80000000'),
- #'sigma' : self.inputs.wf_parameters.get_dict().get('sigma', '0.00500000')}
- change_dict = {'band': True, 'ndir' : 0, 'minEnergy' : emin,
- 'maxEnergy' : emax, 'sigma' : sigma} #'ndir' : 1, 'pot8' : True
-
- fleurmode.set_inpchanges(change_dict)
-
- if nkpts:
- fleurmode.set_nkpts(count=nkpts)
- #fleurinp_new.replace_tag()
-
- fleurmode.show(validate=True, display=False) # needed?
- fleurinp_new = fleurmode.freeze()
- self.ctx.fleurinp1 = fleurinp_new
- #print(fleurinp_new)
- #print(fleurinp_new.folder.get_subfolder('path').get_abs_path(''))
-
- def run_fleur(self):
- """
- run a FLEUR calculation
- """
- fleurin = self.ctx.fleurinp1
- remote = self.inputs.remote
- code = self.inputs.fleur
-
- options = {"max_wallclock_seconds": self.ctx.walltime_sec,
- "resources": self.ctx.resources,
- "queue_name" : self.ctx.queue}
-
- inputs = get_inputs_fleur(code, remote, fleurin, options, serial=self.ctx.serial)
- future = submit(FleurProcess, **inputs)
-
- return ToContext(last_calc=future) #calcs.append(future),
-
-
-
- def return_results(self):
- '''
- return the results of the calculations
- '''
- # TODO more here
- print('Band workflow Done')
- print(('A bandstructure was calculated for fleurinpdata {} and is found under pk={}, '
- 'calculation {}'.format(self.inputs.fleurinp, self.ctx.last_calc.pk, self.ctx.last_calc)))
-
- #check if band file exists: if not succesful = False
- #TODO be careful with general bands.X
-
- bandfilename = 'bands.1' # ['bands.1', 'bands.2', ...]
- # TODO this should be easier...
- last_calc_retrieved = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path('')
- bandfilepath = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path(bandfilename)
- print(bandfilepath)
- #bandfilepath = "path to bandfile" # Array?
- if os.path.isfile(bandfilepath):
- self.ctx.successful = True
- else:
- bandfilepath = None
- print('!NO bandstructure file was found, something went wrong!')
- #TODO corret efermi:
- # get efermi from last calculation
- efermi1 = self.inputs.remote.get_inputs()[-1].res.fermi_energy
- #get efermi from this caclulation
- efermi2 = self.ctx.last_calc.res.fermi_energy
- diff_efermi = efermi1 - efermi2
- # store difference in output node
- # adjust difference in band.gnu
- #filename = 'gnutest2'
-
- outputnode_dict ={}
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['Warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['diff_efermi'] = diff_efermi
- #outputnode_dict['last_calc_pk'] = self.ctx.last_calc.pk
- #outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['bandfile'] = bandfilepath
- outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['last_calc_retrieved'] = last_calc_retrieved
- #print outputnode_dict
- outputnode = Dict(dict=outputnode_dict)
- outdict = {}
- #TODO parse Bandstructure
- #bandstructurenode = ''
- #outdict['output_band'] = bandstructurenode
- #or if spin =2
- #outdict['output_band1'] = bandstructurenode1
- #outdict['output_band2'] = bandstructurenode1
- outdict['output_band_wf_para'] = outputnode
- #print outdict
- for k, v in six.iteritems(outdict):
- self.out(k, v)
-
-
-
-
-#TODO import from somewhere?
-@wf
-def seekpath_structure(structure):
-
- seekpath_info = get_path(structure)
- explicit_path = get_explicit_k_path(structure)
-
- primitive_structure = seekpath_info.pop('primitive_structure')
- conv_structure = seekpath_info.pop('conv_structure')
- parameters = Dict(dict=seekpath_info)
-
- result = {
- 'parameters': parameters,
- 'conv_structure': conv_structure,
- 'primitive_structure': primitive_structure,
- 'explicit_kpoints_path': explicit_path['explicit_kpoints'],
- }
-
- return result
diff --git a/aiida_fleur/workflows/banddos.py b/aiida_fleur/workflows/banddos.py
index 50189f727..2ed2f6349 100644
--- a/aiida_fleur/workflows/banddos.py
+++ b/aiida_fleur/workflows/banddos.py
@@ -60,7 +60,7 @@ class FleurBandDosWorkChain(WorkChain):
'import_sys_environment': False,
'environment_variables': {}
}
- _wf_default = {
+ _default_wf_para = {
'fleur_runmax': 4,
'kpath': 'auto',
# 'nkpts' : 800,
@@ -71,7 +71,7 @@ class FleurBandDosWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurBandDosWorkChain, cls).define(spec)
+ super().define(spec)
# spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
spec.input('fleur', valid_type=Code, required=True)
@@ -120,7 +120,7 @@ def start(self):
inputs = self.inputs
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in inputs:
wf_dict = inputs.wf_parameters.get_dict()
else:
@@ -301,11 +301,16 @@ def return_results(self):
efermi_scf = scf_results.fermi_energy
bandgap_scf = scf_results.bandgap
- efermi_band = last_calc_out_dict['fermi_energy']
- bandgap_band = last_calc_out_dict['bandgap']
+ efermi_band = last_calc_out_dict.get('fermi_energy', None)
+ bandgap_band = last_calc_out_dict.get('bandgap', None)
- diff_efermi = efermi_scf - efermi_band
- diff_bandgap = bandgap_scf - bandgap_band
+ diff_efermi = None
+ if efermi_band is not None:
+ diff_efermi = efermi_scf - efermi_band
+
+ diff_bandgap = None
+ if bandgap_band is not None:
+ diff_bandgap = bandgap_scf - bandgap_band
outputnode_dict = {}
diff --git a/aiida_fleur/workflows/base_fleur.py b/aiida_fleur/workflows/base_fleur.py
index 2c428e556..daadc01df 100644
--- a/aiida_fleur/workflows/base_fleur.py
+++ b/aiida_fleur/workflows/base_fleur.py
@@ -39,7 +39,7 @@ class FleurBaseWorkChain(BaseRestartWorkChain):
@classmethod
def define(cls, spec):
- super(FleurBaseWorkChain, cls).define(spec)
+ super().define(spec)
spec.input('code', valid_type=orm.Code, help='The FLEUR code.')
spec.input('parent_folder',
valid_type=orm.RemoteData,
@@ -174,8 +174,8 @@ def check_kpts(self):
self.ctx.suggest_mpi_omp_ratio,
fleurinp,
only_even_MPI=self.inputs.only_even_MPI)
- except ValueError:
- raise Warning('Not optimal computational resources, load less than 60%')
+ except ValueError as exc:
+ raise Warning('Not optimal computational resources, load less than 60%') from exc
self.report(message)
diff --git a/aiida_fleur/workflows/base_relax.py b/aiida_fleur/workflows/base_relax.py
index dc18c2fdf..deb41dd5f 100644
--- a/aiida_fleur/workflows/base_relax.py
+++ b/aiida_fleur/workflows/base_relax.py
@@ -41,7 +41,7 @@ class FleurBaseRelaxWorkChain(BaseRestartWorkChain):
@classmethod
def define(cls, spec):
- super(FleurBaseRelaxWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(RelaxProcess)
spec.input('description',
valid_type=six.string_types,
@@ -89,7 +89,11 @@ def pop_non_stacking_inpxml_changes(self):
"""
pops some inpxml_changes that do not stack, for example shift_value.
"""
- wf_param = self.ctx.inputs.scf.wf_parameters.get_dict()
+ if 'wf_parameters' in self.ctx.inputs.scf:
+ wf_param = self.ctx.inputs.scf.wf_parameters.get_dict()
+ else:
+ wf_param = {}
+
if 'inpxml_changes' not in wf_param:
return
diff --git a/aiida_fleur/workflows/corehole.py b/aiida_fleur/workflows/corehole.py
index b6ee6391f..243cb3bb1 100644
--- a/aiida_fleur/workflows/corehole.py
+++ b/aiida_fleur/workflows/corehole.py
@@ -99,8 +99,8 @@ class fleur_corehole_wc(WorkChain):
# #'references' : 'calculate',# at some point aiida will have fast forwarding
# 'relax' : False, # relax the unit cell first?
# 'relax_mode': 'Fleur', # what releaxation do you want
- # 'relax_para' : 'default', # parameter dict for the relaxation
- # 'scf_para' : 'default', # wf parameter dict for the scfs
+ # 'relax_para' : None, # parameter dict for the relaxation
+ # 'scf_para' : None, # wf parameter dict for the scfs
# 'same_para' : True, # enforce the same atom parameter/cutoffs on the corehole calc and ref
# 'resources' : {"num_machines": 1},# resources per job
# 'max_wallclock_seconds' : 6*60*60, # walltime per job
@@ -126,61 +126,36 @@ class fleur_corehole_wc(WorkChain):
#'import_sys_environment': False,
#'environment_variables': {}
}
+ _default_wf_para = {
+ 'method': 'valence', # what method to use, default for valence to highest open shell
+ 'hole_charge': 1.0, # what is the charge of the corehole? 0<1.0
+ 'atoms':
+ ['all'], # coreholes on what atoms, positions or index for list, or element ['Be', (0.0, 0.5, 0.334), 3]
+ 'corelevel': ['all'], # coreholes on which corelevels [ 'Be1s', 'W4f', 'Oall'...]
+ 'supercell_size': [2, 1, 1], # size of the supercell [nx,ny,nz]
+ 'para_group': None, # use parameter nodes from a parameter group
+ #'references' : 'calculate',# at some point aiida will have fast forwarding
+ #'relax' : False, # relax the unit cell first?
+ #'relax_mode': 'Fleur', # what releaxation do you want
+ #'relax_para' : None, # parameter dict for the relaxation
+ 'scf_para': None, # wf parameter dict for the scfs
+ 'same_para': True, # enforce the same atom parameter/cutoffs on the corehole calc and ref
+ 'serial': True, # run fleur in serial, or parallel?
+ #'job_limit' : 100 # enforce the workflow not to spawn more scfs wcs then this number(which is roughly the number of fleur jobs)
+ 'magnetic': True
+ }
@classmethod
def define(cls, spec):
- super(fleur_corehole_wc, cls).define(spec)
- spec.input(
- 'wf_parameters',
- valid_type=Dict,
- required=False,
- #default=Dict(
- # dict={
- # 'method':
- # 'valence', # what method to use, default for valence to highest open shell
- # 'hole_charge': 1.0, # what is the charge of the corehole? 0<1.0
- # 'atoms': [
- # 'all'
- # ], # coreholes on what atoms, positions or index for list, or element ['Be', (0.0, 0.5, 0.334), 3]
- # 'corelevel': ['all'
- # ], # coreholes on which corelevels [ 'Be1s', 'W4f', 'Oall'...]
- # 'supercell_size': [2, 1, 1], # size of the supercell [nx,ny,nz]
- # 'para_group': None, # use parameter nodes from a parameter group
- # #'references' : 'calculate',# at some point aiida will have fast forwarding
- # #'relax' : False, # relax the unit cell first?
- # #'relax_mode': 'Fleur', # what releaxation do you want
- # #'relax_para' : 'default', # parameter dict for the relaxation
- # 'scf_para': 'default', # wf parameter dict for the scfs
- # 'same_para':
- # True, # enforce the same atom parameter/cutoffs on the corehole calc and ref
- # 'serial': True, # run fleur in serial, or parallel?
- # #'job_limit' : 100 # enforce the workflow not to spawn more scfs wcs then this number(which is roughly the number of fleur jobs)
- # 'magnetic': True
- # }
- #)
- )
+ super().define(spec)
+ spec.input('wf_parameters', valid_type=Dict, required=False, default=lambda: Dict(dict=cls._default_wf_para))
spec.input('fleurinp', valid_type=FleurinpData, required=False)
spec.input('fleur', valid_type=Code, required=True)
spec.input('inpgen', valid_type=Code, required=True)
spec.input('structure', valid_type=StructureData, required=False)
spec.input('calc_parameters', valid_type=Dict, required=False)
- spec.input(
- 'options',
- valid_type=Dict,
- required=False #,
- #default=Dict(
- # dict={
- # 'resources': {
- # "num_machines": 1, "num_mpiprocs_per_machine": 1,
- # },
- # 'max_wallclock_seconds': 60 * 60,
- # 'queue_name': '',
- # 'custom_scheduler_commands': '',
- # 'import_sys_environment': False,
- # 'environment_variables': {}
- # }
- #)
- )
+ spec.input('options', valid_type=Dict, required=False) #, default=lambda: Dict(dict=cls._default_options))
+
spec.outline(
cls.check_input, # first check if input is consistent
if_(cls.relaxation_needed)( # ggf relax the given cell
@@ -648,8 +623,8 @@ def create_coreholes(self):
#pprint('inpxml_changes {}'.format(corehole['inpxml_changes']))
# create_wf para or write in last line what should be in 'fleur_change'
# for scf, which with the changes in the inp.xml needed
- para = self.ctx.scf_para.copy() # Otherwise inline edit... What about Provenance? TODO check
- if para == 'default':
+ para = self.ctx.scf_para # Otherwise inline edit... What about Provenance? TODO check
+ if para is None:
wf_parameter = {}
else:
wf_parameter = para
@@ -697,7 +672,7 @@ def run_ref_scf(self):
self.report('INFO: In run_ref_scf fleur_corehole_wc')
print('INFO: In run_ref_scf fleur_corehole_wc')
para = self.ctx.scf_para
- if para == 'default':
+ if para is None:
wf_parameter = {}
else:
wf_parameter = para
@@ -841,7 +816,7 @@ def run_scfs(self):
self.report('INFO: In run_scfs fleur_corehole_wc')
print('INFO: In run_scfs fleur_corehole_wc')
para = self.ctx.scf_para
- if para == 'default':
+ if para is None:
wf_parameter = {}
else:
wf_parameter = para
@@ -1098,7 +1073,9 @@ def create_corehole_result_node(**kwargs): #*args):
# 'inpxml_changes' : fleurinp_change}
@cf
def prepare_struc_corehole_wf(
- base_supercell, wf_para, para
+ base_supercell,
+ wf_para,
+ para=None,
): #, _label='prepare_struc_corehole_wf', _description='WF, used in the corehole_wc, breaks the symmetry and moves the cell, prepares the inpgen parameters for a corehole.'):
"""
calcfunction which does all/some the structure+calcparameter manipulations together
@@ -1106,6 +1083,7 @@ def prepare_struc_corehole_wf(
wf_para: Dict node dict: {'site' : sites[8], 'kindname' : 'W1', 'econfig': "[Kr] 5s2 4d10 4f13 | 5p6 5d5 6s2", 'fleurinp_change' : []}
"""
from aiida_fleur.tools.StructureData_util import move_atoms_incell
+
#from aiida.orm.data.structure import Site
wf_para_dict = wf_para.get_dict()
@@ -1120,12 +1098,14 @@ def prepare_struc_corehole_wf(
npos = -np.array(pos)
# break the symmetry, make corehole atoms its own species. # pos has to be tuple, unpack problem here.. #TODO rather not so nice
- new_struc, new_para = break_symmetry(base_supercell,
- atoms=[],
- site=[],
- pos=[(pos[0], pos[1], pos[2])],
- new_kinds_names=new_kinds_names,
- parameterdata=para)
+ inputs = dict(structure=base_supercell,
+ atoms=[],
+ site=[],
+ pos=[(pos[0], pos[1], pos[2])],
+ new_kinds_names=new_kinds_names)
+ if para is not None:
+ inputs['parameterdata'] = para
+ new_struc, new_para = break_symmetry(**inputs)
#kinds = new_struc.kinds
#for kind in kinds:
# if kind.name == broke_kn:
@@ -1160,11 +1140,12 @@ def extract_results_corehole(calcs):
print(calc.exit_status, calc.exit_message)
print(calc.get_outgoing().all())
try:
- calc_uuids.append(calc.outputs.output_scf_wc_para.get_dict()['last_calc_uuid'])
+ calc_uuid = calc.outputs.output_scf_wc_para.get_dict()['last_calc_uuid']
except (KeyError, AttributeError):
print('continue')
continue
- #calc_uuids.append(calc['output_scf_wc_para'].get_dict()['last_calc_uuid'])
+ if calc_uuid is not None:
+ calc_uuids.append(calc_uuid)
#print(calc_uuids)
#all_corelevels = {}
diff --git a/aiida_fleur/workflows/corelevel.py.legacy b/aiida_fleur/workflows/corelevel.py.legacy
deleted file mode 100644
index 1f3dff4c9..000000000
--- a/aiida_fleur/workflows/corelevel.py.legacy
+++ /dev/null
@@ -1,258 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-
-
-"""
-This is the worklfow 'corelevel' using the Fleur code, which calculates Binding
-energies and corelevel shifts with different methods.
-'divide and conquer'
-"""
-# TODO alow certain kpoint path, or kpoint node, so far auto
-
-
-from __future__ import absolute_import
-from __future__ import print_function
-import os.path
-from aiida.plugins import Code, DataFactory
-from aiida.engine import WorkChain
-from aiida.engine import submit
-from aiida.engine import ToContext
-from aiida.engine import while_, if_
-#from aiida.work.process_registry import ProcessRegistry
-
-from aiida_fleur.calculation.fleur import FleurCalculation
-from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
-from aiida_fleur.tools.create_corehole import create_corehole
-import six
-
-StructureData = DataFactory('structure')
-Dict = DataFactory('dict')
-RemoteData = DataFactory('remote')
-FleurinpData = DataFactory('fleur.fleurinp')
-FleurProcess = FleurCalculation.process()
-
-
-class fleur_corelevel_wc(WorkChain):
- '''
- Turn key solution for the calculation of core level shift and Binding energies
-
-
- '''
- # wf_Parameters: Dict,
- '''
- 'method' : ['initial', 'full_valence ch', 'half_valence_ch', 'ch', ...]
- 'Bes' : [W4f, Be1s]
- 'CLS' : [W4f, Be1s]
- 'atoms' : ['all', 'postions' : []]
- 'references' : ['calculate', or
- 'scf_para' : {...}, 'default'
- 'relax' : True
- 'relax_mode': ['Fleur', 'QE Fleur', 'QE']
- 'relax_para' : {...}, 'default'
- 'calculate_doses' : False
- 'dos_para' : {...}, 'default'
- '''
- '''
- # defaults
- default wf_Parameters::
- 'method' : 'initial'
- 'atoms' : 'all
- 'references' : 'calculate'
- 'scf_para' : 'default'
- 'relax' : True
- 'relax_mode': 'QE Fleur'
- 'relax_para' : 'default'
- 'calculate_doses' : False
- 'dos_para' : 'default'
- '''
-
- _workflowversion = "0.0.1"
-
- @classmethod
- def define(cls, spec):
- super(corelevel, cls).define(spec)
- spec.input("wf_parameters", valid_type=Dict, required=False,
- default=Dict(dict={
- 'method' : 'initial',
- 'atoms' : 'all',
- 'references' : 'calculate',
- 'calculate_doses' : False,
- 'relax' : True,
- 'relax_mode': 'QE Fleur',
- 'relax_para' : 'default',
- 'scf_para' : 'default',
- 'dos_para' : 'default'}))
- spec.input("fleurinp", valid_type=FleurinpData, required=True)
- spec.input("fleur", valid_type=Code, required=True)
- spec.input("structure", valid_type=StructureData, required=False)
- spec.input("calc_parameters", valid_type=Dict, required=False)
- spec.outline(
- cls.check_input,
- if_(cls.initalstate)(
- cls.calculate_inital),
- cls.create_new_fleurinp,
- cls.run_fleur,
- cls.run_scfs,
- cls.collect_results,
- cls.return_results
- )
- #spec.dynamic_output()
-
-
- def start(self):
- '''
- check parameters, what condictions? complete?
- check input nodes
- '''
- ### input check ### ? or done automaticly, how optional?
- # check if fleuinp corresponds to fleur_calc
- print(('started bands workflow version {}'.format(self._workflowversion)))
- print("Workchain node identifiers: ")#{}"
- #"".format(ProcessRegistry().current_calc_node))
-
-
-
- def create_new_fleurinp(self):
- """
- create a new fleurinp from the old with certain parameters
- """
- # TODO allow change of kpoint mesh?, tria?
- wf_dict = self.inputs.wf_parameters.get_dict()
- nkpts = wf_dict.get('nkpts', 500)
- # how can the user say he want to use the given kpoint mesh, ZZ nkpts : False/0
- sigma = wf_dict.get('sigma', 0.005)
- emin = wf_dict.get('emin', -0.30)
- emax = wf_dict.get('emax', 0.80)
-
- fleurmode = FleurinpModifier(self.inputs.fleurinp)
-
- #change_dict = {'band': True, 'ndir' : -1, 'minEnergy' : self.inputs.wf_parameters.get_dict().get('minEnergy', -0.30000000),
- #'maxEnergy' : self.inputs.wf_parameters.get_dict().get('manEnergy','0.80000000'),
- #'sigma' : self.inputs.wf_parameters.get_dict().get('sigma', '0.00500000')}
- change_dict = {'band': True, 'ndir' : 0, 'minEnergy' : emin,
- 'maxEnergy' : emax, 'sigma' : sigma} #'ndir' : 1, 'pot8' : True
-
- fleurmode.set_inpchanges(change_dict)
-
- if nkpts:
- fleurmode.set_nkpts(count=nkpts)
- #fleurinp_new.replace_tag()
-
- fleurmode.show(validate=True, display=False) # needed?
- fleurinp_new = fleurmode.freeze()
- self.ctx.fleurinp1 = fleurinp_new
- print(fleurinp_new)
- #print(fleurinp_new.folder.get_subfolder('path').get_abs_path(''))
-
- def get_inputs_fleur(self):
- '''
- get the input for a FLEUR calc
- '''
- inputs = FleurProcess.get_inputs_template()
-
- fleurin = self.ctx.fleurinp1
- #print fleurin
- remote = self.inputs.remote
- inputs.parent_folder = remote
- inputs.code = self.inputs.fleur
- inputs.fleurinpdata = fleurin
-
- # TODO nkpoints decide n core
-
- core = 12 # get from computer nodes per machine
- inputs._options.resources = {"num_machines": 1, "num_mpiprocs_per_machine" : core}
- inputs._options.max_wallclock_seconds = 30 * 60
-
- if self.ctx.serial:
- inputs._options.withmpi = False # for now
- inputs._options.resources = {"num_machines": 1}
-
- if self.ctx.queue:
- inputs._options.queue_name = self.ctx.queue
- print((self.ctx.queue))
- # if code local use
- #if self.inputs.fleur.is_local():
- # inputs._options.computer = computer
- # #else use computer from code.
- #else:
- # inputs._options.queue_name = 'th1'
-
- if self.ctx.serial:
- inputs._options.withmpi = False # for now
- inputs._options.resources = {"num_machines": 1}
-
- return inputs
-
- def run_fleur(self):
- '''
- run a fleur calculation
- '''
- FleurProcess = FleurCalculation.process()
- inputs = {}
- inputs = self.get_inputs_fleur()
- #print inputs
- future = submit(FleurProcess, **inputs)
- print('run Fleur in band workflow')
-
- return ToContext(last_calc=future)
-
- def return_results(self):
- '''
- return the results of the calculations
- '''
- # TODO more here
- print('Band workflow Done')
- print(('A bandstructure was calculated for fleurinpdata {} and is found under pk={}, '
- 'calculation {}'.format(self.inputs.fleurinp, self.ctx.last_calc.pk, self.ctx.last_calc)))
-
- #check if band file exists: if not succesful = False
- #TODO be careful with general bands.X
-
- bandfilename = 'bands.1' # ['bands.1', 'bands.2', ...]
- # TODO this should be easier...
- last_calc_retrieved = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path')
- bandfilepath = self.ctx.last_calc.get_outputs_dict()['retrieved'].folder.get_subfolder('path').get_abs_path(bandfilename)
- print(bandfilepath)
- #bandfilepath = "path to bandfile" # Array?
- if os.path.isfile(bandfilepath):
- self.ctx.successful = True
- else:
- bandfilepath = None
- print('!NO bandstructure file was found, something went wrong!')
- #TODO corret efermi:
- # get efermi from last calculation
- efermi1 = self.inputs.remote.get_inputs()[-1].res.fermi_energy
- #get efermi from this caclulation
- efermi2 = self.ctx.last_calc.res.fermi_energy
- diff_efermi = efermi1 - efermi2
- # store difference in output node
- # adjust difference in band.gnu
- #filename = 'gnutest2'
-
- outputnode_dict ={}
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['Warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['diff_efermi'] = diff_efermi
- #outputnode_dict['last_calc_pk'] = self.ctx.last_calc.pk
- #outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['bandfile'] = bandfilepath
- outputnode_dict['last_calc_uuid'] = self.ctx.last_calc.uuid
- outputnode_dict['last_calc_retrieved'] = last_calc_retrieved
- #print outputnode_dict
- outputnode = Dict(dict=outputnode_dict)
- outdict = {}
- outdict['band_out'] = outputnode
- #print outdict
- for k, v in six.iteritems(outdict):
- self.out(k, v)
diff --git a/aiida_fleur/workflows/create_magnetic_film.py b/aiida_fleur/workflows/create_magnetic_film.py
index 25224d5df..b5fcb54ac 100644
--- a/aiida_fleur/workflows/create_magnetic_film.py
+++ b/aiida_fleur/workflows/create_magnetic_film.py
@@ -34,7 +34,7 @@ class FleurCreateMagneticWorkChain(WorkChain):
"""
_workflowversion = '0.1.2'
- _wf_default = {
+ _default_wf_para = {
'lattice': 'fcc',
'miller': [[-1, 1, 0], [0, 0, 1], [1, 1, 0]],
'host_symbol': 'Pt',
@@ -53,7 +53,7 @@ class FleurCreateMagneticWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurCreateMagneticWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurEosWorkChain,
namespace_options={
'required': False,
@@ -133,7 +133,7 @@ def start(self):
self.ctx.substrate = None
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
diff --git a/aiida_fleur/workflows/delta.py b/aiida_fleur/workflows/delta.py
deleted file mode 100644
index 5df0bf867..000000000
--- a/aiida_fleur/workflows/delta.py
+++ /dev/null
@@ -1,614 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-"""
-In this module you find the worklfow 'fleur_delta_wc' which is a turnkey solution to calculate a delta for a given code with AiiDA.
-"""
-#TODO: calculation of delta value from the files
-# submit everything if subworkchaining works in Aiida
-# parameter node finding is not optimal.
-
-# TODO several eos starts wich only 20 structures to limit jobs throughput
-from __future__ import absolute_import
-from __future__ import print_function
-import os
-import six
-from string import digits
-#from pprint import pprint
-
-from aiida.plugins import DataFactory
-from aiida.orm import Code, Group
-from aiida.orm import RemoteData, StructureData, Dict, SinglefileData
-from aiida.engine import WorkChain, ToContext #, while_
-#from aiida.work.process_registry import ProcessRegistry
-from aiida.engine import calcfunction as cf
-from aiida.engine import submit
-from aiida.common.exceptions import NotExistent
-
-from aiida_fleur.workflows.eos import FleurEosWorkChain
-from aiida_fleur.data.fleurinp import FleurinpData
-
-
-class fleur_delta_wc(WorkChain):
- """
- This workflow calculates a equation of states and from a given
- group of structures in the database using a group of given parameter nodes in the database
- """
-
- _workflowversion = '0.3.2'
- _wf_default = {}
-
- @classmethod
- def define(cls, spec):
- super(fleur_delta_wc, cls).define(spec)
- spec.input(
- 'wf_parameters',
- valid_type=Dict,
- required=False,
- default=Dict(
- dict={
- 'struc_group': 'delta',
- 'para_group': 'delta',
- 'add_extra': {
- 'type': 'delta run'
- },
- #'group_label' : 'delta_eos',
- 'joblimit': 100,
- 'part': [1, 2, 3, 4],
- 'points': 7,
- 'step': 0.02
- }))
- spec.input('options',
- valid_type=Dict,
- required=False,
- default=Dict(
- dict={
- 'resources': {
- 'num_machines': 1
- },
- 'walltime_sec': 60 * 60,
- 'queue_name': '',
- 'custom_scheduler_commands': '',
- 'import_sys_environment': False,
- 'environment_variables': {}
- }))
- spec.input('inpgen', valid_type=Code, required=True)
- spec.input('fleur', valid_type=Code, required=True)
- spec.outline(
- cls.start_up,
- #while_(cls.calculations_left_torun)(
- cls.run_eos, #),
- cls.extract_results_eos,
- cls.calculate_delta,
- cls.return_results,
- )
- #spec.dynamic_output()
-
- def start_up(self):
- """
- init context and some parameters
- """
-
- #print('started delta workflow version {}'.format(self._workflowversion))
- #print("Workchain node identifiers: {}".format(ProcessRegistry().current_calc_node))
- #identifier = 0#ProcessRegistry().current_calc_node
- #self.ctx.own_uuid = identifier.uuid
- #self.ctx.own_pk = identifier.pk
-
- self.report('started delta workflow version {} with identifier: ' #{}'
- ''.format(self._workflowversion)) #, identifier))
-
- # init
- self.ctx.calcs_to_run = []
- # input check
-
- # check if right codes
- wf_dict = self.inputs.wf_parameters.get_dict()
- options_dict = self.inputs.get('options',
- Dict(dict={
- 'resources': {
- 'num_machines': 1
- },
- 'walltime_sec': int(5.5 * 3600)
- }))
- self.ctx.inputs_eos = {
- 'fleur': self.inputs.fleur,
- 'inpgen': self.inputs.inpgen,
- 'wf_parameters': {
- 'points': wf_dict.get('points', 7),
- 'step': wf_dict.get('step', 0.02),
- 'guess': 1.0
- },
- 'options': options_dict
- }
- self.ctx.wc_eos_para = Dict(dict=self.ctx.inputs_eos.get('wf_parameters'))
- self.ctx.ncalc = 1 # init
- self.get_calcs_from_groups()
- self.ctx.successful = True
- self.ctx.warnings = []
- self.ctx.labels = []
- #self.ctx.calcs_to_run = calcs
- self.ctx.ncalcs = len(self.ctx.calcs_to_run)
- print((self.ctx.ncalcs))
- print((self.ctx.ncalc))
- estimated_jobs = self.ctx.ncalc * wf_dict.get('points', 5)
- joblimit = wf_dict.get('joblimit', 90)
- self.ctx.eos_run_steps = 1
- self.ctx.eos_steps_done = 0
- self.ctx.minindex = 0
- self.ctx.maxindex = self.ctx.ncalc - 1
- self.ctx.eos_max_perstep = 10000 # init
-
- if estimated_jobs >= joblimit:
- self.ctx.eos_run_steps = estimated_jobs / joblimit + 1
- self.ctx.eos_max_perstep = joblimit / wf_dict.get('points', 5)
- # TODO be carefull if is not a divisor... of joblimit
- self.ctx.maxindex = 0 # will be set later self.ctx.eos_max_perstep
-
- self.report('{} {}'.format(self.ctx.ncalc, self.ctx.eos_max_perstep))
- self.report('Estimated fleur scfs to run {}, running in {} steps.'
- ''.format(estimated_jobs, self.ctx.eos_run_steps))
-
- def get_calcs_from_groups(self):
- """
- Extract the crystal structures and parameter data nodes from the given
- groups and create calculation 'pairs' (stru, para).
- """
- wf_dict = self.inputs.wf_parameters.get_dict()
- #get all delta structure
- str_gr = wf_dict.get('struc_group', 'delta')
-
- try:
- group_pk = int(str_gr)
- except ValueError:
- group_pk = None
- group_name = str_gr
-
- if group_pk is not None:
- try:
- str_group = Group(label=group_pk)
- except NotExistent:
- str_group = None
- message = ('You have to provide a valid pk for a Group of'
- 'structures or a Group name. Wf_para key: "struc_group".'
- 'given pk= {} is not a valid group'
- '(or is your group name integer?)'.format(group_pk))
- #print(message)
- self.report(message)
- self.abort_nowait('I abort, because I have no structures to calculate ...')
- else:
- try:
- str_group = Group.get_from_string(group_name)
- except NotExistent:
- str_group = None
- message = ('You have to provide a valid pk for a Group of'
- 'structures or a Group name. Wf_para key: "struc_group".'
- 'given group name= {} is not a valid group'
- '(or is your group name integer?)'.format(group_name))
- #print(message)
- self.report(message)
- self.abort_nowait('I abort, because I have no structures to calculate ...')
-
- #get all delta parameters
- para_gr = wf_dict.get('para_group', 'delta')
-
- if not para_gr:
- #waring use defauls
- message = 'COMMENT: I did recieve "para_group=None" as input. I will use inpgen defaults'
- self.report(message)
-
- try:
- group_pk = int(para_gr)
- except ValueError:
- group_pk = None
- group_name = para_gr
-
- if group_pk is not None:
- try:
- para_group = Group(label=group_pk)
- except NotExistent:
- para_group = None
- message = ('ERROR: You have to provide a valid pk for a Group of'
- 'parameters or a Group name (or use None for inpgen defaults). Wf_para key: "para_group".'
- 'given pk= {} is not a valid group'
- '(or is your group name integer?)'.format(group_pk))
- #print(message)
- self.report(message)
- self.abort_nowait('ERROR: I abort, because I have no paremeters to calculate and '
- 'I guess you did not want to use the inpgen default...')
- else:
- try:
- para_group = Group.get_from_string(group_name)
- except NotExistent:
- para_group = None
- message = ('ERROR: You have to provide a valid pk for a Group of'
- 'parameters or a Group name (or use None for inpgen defaults). Wf_para key: "struc_group".'
- 'given group name= {} is not a valid group'
- '(or is your group name integer?)'.format(group_name))
- #print(message)
- self.report(message)
- self.abort_nowait('ERROR: I abort, because I have no paremeters to calculate and '
- 'I guess you did not want to use the inpgen default...')
-
- # creating calculation pairs (structure, parameters)
-
- para_nodesi = para_group.nodes
- para_nodes = []
-
- for para in para_nodesi:
- para_nodes.append(para)
- #print para_nodes
- n_para = len(para_nodes)
- stru_nodes = str_group.nodes
- n_stru = len(stru_nodes)
- if n_para != n_stru:
- message = ('COMMENT: You did not provide the same number of parameter'
- 'nodes as structure nodes. Is this wanted? npara={} nstru={}'.format(n_para, n_stru))
- self.report(message)
- calcs = []
- for struc in stru_nodes:
- para = get_paranode(struc, para_nodes)
- #if para:
- calcs.append((struc, para))
- #else:
- # calcs.append((struc))
- #pprint(calcs[:20])
- self.ctx.calcs_to_run = calcs
- self.ctx.ncalc = len(calcs)
-
- #def calculations_left_torun(self):
- # """
- # Checks if there are still some equations of states to run
- # """
- # calculations_left = True
- # self.ctx.last_step = False
- #
- # if self.ctx.eos_steps_done == self.ctx.eos_run_steps:
- # calculations_left = False
- # if (self.ctx.eos_steps_done + 1) == self.ctx.eos_run_steps:
- # self.ctx.last_step = True
- #
- # return calculations_left
-
- def run_eos(self):
- """
- Run the equation of states for all delta structures with their parameters
- """
- #if self.ctx.last_step:
- # self.ctx.maxindex = None
- #else:
- # self.ctx.maxindex = self.ctx.maxindex + self.ctx.eos_max_perstep
-
- #self.report('Submitting eqaution of states part {} out of {}, from {} to {}'
- # ''.format(self.ctx.eos_steps_done, self.ctx.eos_run_steps,
- # self.ctx.minindex, self.ctx.maxindex))
-
- eos_results = {}
- inputs = self.get_inputs_eos()
-
- #print(self.ctx.minindex)
- #print(self.ctx.maxindex)
-
- for struc, para in self.ctx.calcs_to_run: #[:4]self.ctx.minindex:self.ctx.maxindex]:#0:0]:#
- #print para
- formula = struc.get_formula()
- label = '|delta_wc|eos|{}'.format(formula)
- description = '|delta| fleur_eos_wc on {}'.format(formula)
- if para:
- eos_future = submit(FleurEosWorkChain,
- wf_parameters=inputs['wc_eos_para'],
- structure=struc,
- options=inputs['options'],
- calc_parameters=para,
- inpgen=inputs['inpgen'],
- fleur=inputs['fleur'],
- label=label,
- description=description)
- else: # TODO: run eos_wc_simple
- eos_future = submit(FleurEosWorkChain,
- wf_parameters=inputs['wc_eos_para'],
- structure=struc,
- options=inputs['options'],
- inpgen=inputs['inpgen'],
- fleur=inputs['fleur'],
- label=label,
- description=description)
- self.report('launching fleur_eos_wc<{}> on structure {} with parameter {}'
- ''.format(eos_future.pid, struc.pk, para.pk))
- label = formula
- self.ctx.labels.append(label)
- eos_results[label] = eos_future
-
- #self.ctx.eos_steps_done = self.ctx.eos_steps_done + 1
- #self.ctx.minindex = self.ctx.maxindex
- '''
- # with run
- eos_results = {}
- inputs = self.get_inputs_eos()
-
-
- for struc, para in self.ctx.calcs_to_run[:]:
- print para
- formula = struc.get_formula()
- if para:
- #print('here')
- eos_future = fleur_eos_wc.run(
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- calc_parameters=para, inpgen=inputs['inpgen'], fleur=inputs['fleur'])
- #fleur_eos_wc.run(#
- else:
- self.report('INFO: default parameters for structure {}'.format(formula))
- eos_future = fleur_eos_wc.run(
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- inpgen=inputs['inpgen'], fleur=inputs['fleur'])
- #fleur_eos_wc.run(#a
- #self.report('launching fleur_eos_wc<{}> on structure {} with parameter {}'
- # ''.format(eos_future.pid, struc.pk, para.pk))
- label = formula
- self.ctx.labels.append(label)
- eos_results[label] = eos_future
-
- return ToContext(**eos_results)
- '''
- return ToContext(**eos_results)
-
- # To limit the troughput of 100 jobs, we create several run eos steps
- def get_inputs_eos(self):
- """
- get the inputs for a scf-cycle
- """
- inputs = {}
- # produce the inputs for a eos worklfow (collect here...)
-
- inputs['wc_eos_para'] = self.ctx.wc_eos_para
- #inputs['calc_parameters'] = self.inputs.calc_parameters
- inputs['inpgen'] = self.ctx.inputs_eos.get('inpgen')
- inputs['fleur'] = self.ctx.inputs_eos.get('fleur')
- inputs['options'] = self.ctx.inputs_eos.get('options')
- return inputs
-
- def extract_results_eos(self):
- """
- extract information out of the result nodes of the the eos workchains
- ran in the step before
- """
-
- self.ctx.all_results = {}
- self.ctx.all_succ = {}
- self.ctx.eos_uuids = {}
- outstr = ('''\
- Delta calculation FLEUR {} (AiiDA wc).
-
- Crystal \t V0 \t \t B0 \t \t BP [A^3/at] \t [GPa] \t \t [--] \n
- '''.format(self.ctx.inputs_eos.get('fleur')))
- filename = 'delta_wc_{}.out'.format(self.ctx.own_pk)
- outfile = open(filename, 'w')
- outfile.write(outstr)
- outfile.close()
- outstr = ''
- for label in self.ctx.labels:
- eos_res = self.ctx[label]
- #print(calc)
- outpara1 = eos_res.get_outputs_dict()
- #print outpara1
- try:
- outpara = outpara1['output_eos_wc_para'].get_dict()
- except KeyError:
- self.report('ERROR: Eos wc for element: {} failed. I retrieved {} '
- 'I skip the results retrieval for that element.'.format(label, eos_res))
- continue
- eos_succ = outpara.get('successful', False)
- if not eos_succ:
- #maybe do something else here (exclude point and write a warning or so, or error treatment)
- self.ctx.successful = False
-
- natoms = outpara.get('natoms', None)
- gs_vol = outpara.get('volume_gs', None)
- bm = outpara.get('bulk_modulus', None)
- #bm_u = outpara.get('bulk_modulus_units', 'GPa')
- dbm = outpara.get('bulk_deriv', None)
- if natoms:
- gs_vol_pera = gs_vol / natoms
- else:
- gs_vol_pera = gs_vol
-
- element = label.translate(None, digits) # remove all numbers from string
- self.ctx.all_results[element] = [gs_vol_pera, bm, dbm]
- self.ctx.all_succ[element] = eos_succ
- self.ctx.eos_uuids[element] = eos_res.get_inputs()[0].uuid
-
- outstr = outstr + '{} \t {:.5f} \t {:.5f} \t {:.5f} \n'.format(element, gs_vol_pera, bm, dbm)
- #write inside the loop to have at least partially results...
- #outfile = open('delta_wc.out', 'a')
- #outstr = '{} \t {:.5f} \t {:.5f} \t {:.5f} \n'.format(element, gs_vol_pera, bm, dbm)
- #outfile.write(outstr)
- #outfile.close()
- # produce a single file
- # maybe put in try(or write in a certain place where is sure that you have the permissions)
- #outfile = open('delta_wc.out', 'w')
- outfile = open(filename, 'a') # for testing purposes
- outfile.write(outstr)
-
- outfile.close()
-
- self.ctx.outfilepath = os.path.abspath(outfile.name)
-
- def calculate_delta(self):
- """
- Execute here the script to calculate a delta factor
- """
- pass
-
- def return_results(self):
- """
- return the results of the calculations
- """
-
- # log some stuff in report
-
- # a text file should be written and stored as single file data and
- #parameter data node in the database
-
- #produce a single file data with all the numbers
-
- all_res = self.ctx.all_results
- self.report('all_res : {}'.format(all_res))
- #print all_res
- bm_dic = {}
- bmd_dic = {}
- vol_dic = {}
-
- for elem, val in six.iteritems(all_res):
- #print elem
- vol_dic[elem] = val[0]
- bm_dic[elem] = val[1]
- bmd_dic[elem] = val[2]
-
- outputnode_dict = {}
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['eos_uuids'] = self.ctx.eos_uuids
- outputnode_dict['eos_success'] = self.ctx.all_succ
- outputnode_dict['bulk_modulus'] = bm_dic
- outputnode_dict['bulk_modulus_units'] = 'GPa'
- outputnode_dict['bulk_modulus_dev'] = bmd_dic
- outputnode_dict['volumes'] = vol_dic
- outputnode_dict['volumes_units'] = 'A^3/per atom'
- outputnode_dict['delta_factor'] = {'Wien2K': '', 'Fleur_026': ''}
-
- #outputnode = Dict(dict=outputnode_dict)
-
- if self.ctx.successful:
- self.report('INFO: Done, delta worklfow complete')
- #print 'Done, delta worklfow complete'
- else:
- self.report('INFO: Done, but something went wrong.... Properly some '
- 'individual eos workchain failed. Check the log.')
- #print('Done, but something went wrong.... Properly some '
- # 'individual eos workchain failed. Check the log.')
-
- delta_file = SinglefileData.filename = self.ctx.outfilepath
-
- print(delta_file)
-
- # output must be aiida Data types.
- outnodedict = {}
- outnode = Dict(dict=outputnode_dict)
- outnodedict['results_node'] = outnode
- for label in self.ctx.labels:
- eos_res = self.ctx[label]
- #print(calc)
- outpara1 = eos_res.get_outputs_dict()
- #print outpara1
- try:
- outpara = outpara1['output_eos_wc_para']
- except KeyError:
- #self.report('ERROR: Eos wc for element: {} failed. I retrieved {} '
- # 'I skip the results retrieval for that element.'.format(label, eos_res))
- continue
- outnodedict[label] = outpara
-
- outputnode = create_delta_result_node(**outnodedict)
-
- outdict = {}
- outdict['output_delta_wc_para'] = outputnode.get('output_delta_wc_para')
- #outdict['delta_file'] = delta_file
- #print outdict
- for link_name, node in six.iteritems(outdict):
- self.out(link_name, node)
-
-
-'''
-if __name__ == "__main__":
- import argparse
-
- parser = argparse.ArgumentParser(description='SCF with FLEUR. workflow to'
- ' converge the chargedensity and optional the total energy.')
- parser.add_argument('--wf_para', type=Dict, dest='wf_parameters',
- help='The pseudopotential family', required=False)
- parser.add_argument('--structure', type=StructureData, dest='structure',
- help='The crystal structure node', required=False)
- parser.add_argument('--calc_para', type=Dict, dest='calc_parameters',
- help='Parameters for the FLEUR calculation', required=False)
- parser.add_argument('--fleurinp', type=FleurinpData, dest='fleurinp',
- help='FleurinpData from which to run the FLEUR calculation', required=False)
- parser.add_argument('--remote', type=RemoteData, dest='remote_data',
- help=('Remote Data of older FLEUR calculation, '
- 'from which files will be copied (mixing_history ...)'), required=False)
- parser.add_argument('--inpgen', type=Code, dest='inpgen',
- help='The inpgen code node to use', required=False)
- parser.add_argument('--fleur', type=Code, dest='fleur',
- help='The FLEUR code node to use', required=True)
-
- args = parser.parse_args()
- res = fleur_scf_wc.run(wf_parameters=args.wf_parameters,
- structure=args.structure,
- calc_parameters=args.calc_parameters,
- fleurinp=args.fleurinp,
- remote_data=args.remote_data,
- inpgen = args.inpgen,
- fleur=args.fleur)
-'''
-
-
-@cf
-def create_delta_result_node(**kwargs): #*args):
- """
- This is a pseudo wf, to create the rigth graph structure of AiiDA.
- This wokfunction will create the output node in the database.
- It also connects the output_node to all nodes the information commes from.
- So far it is just also parsed in as argument, because so far we are to lazy
- to put most of the code overworked from return_results in here.
-
- """
- outdict = {}
- outpara = kwargs.get('results_node', {})
- outdict['output_delta_wc_para'] = outpara.clone()
- # copy, because we rather produce the same node twice then have a circle in the database for now...
- #output_para = args[0]
- #return {'output_eos_wc_para'}
- return outdict
-
-
-def get_paranode(struc, para_nodes):
- """
- find out if a parameter node for a structure is in para_nodes
- (currently very creedy, but lists are small (100x100) but maybe reduce database accesses)
- """
-
- suuid = struc.uuid
- formula = struc.get_formula()
- element = formula.translate(None, digits)
- #print para_nodes
- for para in para_nodes:
- struc_uuid = para.get_extra('struc_uuid', None)
- para_form = para.get_extra('formula', None)
- para_ele = para.get_extra('element', None)
- if suuid == struc_uuid:
- return para
- elif formula == para_form:
- return para
- elif element == para_ele:
- return para
- elif element == para_form:
- return para
- else:
- pass
- #Do something else (test if parameters for a certain element are there)
- #....
- # we found no parameter node for the given structure therefore return none
- return None
-
-
-def write_delta_file(result_dict):
- pass
diff --git a/aiida_fleur/workflows/delta_split.py.legacy b/aiida_fleur/workflows/delta_split.py.legacy
deleted file mode 100644
index a06c9fe37..000000000
--- a/aiida_fleur/workflows/delta_split.py.legacy
+++ /dev/null
@@ -1,588 +0,0 @@
-# -*- coding: utf-8 -*-
-###############################################################################
-# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
-# All rights reserved. #
-# This file is part of the AiiDA-FLEUR package. #
-# #
-# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
-# For further information on the license, see the LICENSE.txt file #
-# For further information please visit http://www.flapw.de or #
-# http://aiida-fleur.readthedocs.io/en/develop/ #
-###############################################################################
-
-"""
-In this module you find the worklfow 'fleur_delta_wc' which is a turnkey solution to calculate a delta for a given code with AiiDA.
-"""
-#TODO: calculation of delta value from the files
-# submit everything if subworkchaining works in Aiida
-# parameter node finding is not optimal.
-
-# TODO several eos starts wich only 20 structures to limit jobs throughput
-from __future__ import absolute_import
-from __future__ import print_function
-import os
-from string import digits
-from pprint import pprint
-
-from aiida.plugins import Code, DataFactory, Group
-from aiida.engine import WorkChain, ToContext, while_
-#from aiida.work.process_registry import ProcessRegistry
-from aiida.engine import workfunction as wf
-from aiida.engine import submit
-from aiida.common.exceptions import NotExistent
-from aiida_fleur.workflows.eos import fleur_eos_wc
-import six
-
-#from aiida_fleur.tools.xml_util import eval_xpath2
-#from lxml import etree
-
-
-RemoteData = DataFactory('remote')
-StructureData = DataFactory('structure')
-Dict = DataFactory('dict')
-FleurinpData = DataFactory('fleur.fleurinp')
-SingleData = DataFactory('singlefile')
-
-class fleur_delta_wc(WorkChain):
- """
- This workflow calculates a equation of states and from a given
- group of structures in the database using a group of given parameter nodes in the database
- """
-
- _workflowversion = "0.0.1"
- _wf_default = {}
-
- def __init__(self, *args, **kwargs):
- super(fleur_delta_wc, self).__init__(*args, **kwargs)
-
- @classmethod
- def define(cls, spec):
- super(fleur_delta_wc, cls).define(spec)
- spec.input("wf_parameters", valid_type=Dict, required=False,
- default=Dict(dict={'struc_group': 'delta',
- 'para_group' : 'delta',
- 'add_extra' : {'type' : 'delta run'},
- #'group_label' : 'delta_eos',
- 'joblimit' : 100,
- 'part' : [1,2,3,4],
- 'points' : 5,
- 'step' : 0.02,
- 'queue_name' : '',
- 'options' : {'resources' : {"num_machines": 1},
- 'walltime_sec' : int(5.5*3600)}}))
- spec.input("inpgen", valid_type=Code, required=True)
- spec.input("fleur", valid_type=Code, required=True)
- spec.outline(
- cls.start_up,
- while_(cls.calculations_left_torun)(
- cls.run_eos),
- cls.extract_results_eos,
- cls.calculate_delta,
- cls.return_results,
-
- )
- #spec.dynamic_output()
-
- def start_up(self):
- """
- init context and some parameters
- """
-
- #print('started delta workflow version {}'.format(self._workflowversion))
- #print("Workchain node identifiers: {}".format(ProcessRegistry().current_calc_node))
- self.report('started delta workflow version {} with idenifier: '#{}'
- ''.format(self._workflowversion))#, ProcessRegistry().current_calc_node))
-
- # init
- self.ctx.calcs_to_run = []
- # input check
-
- # check if right codes
- wf_dict = self.inputs.wf_parameters.get_dict()
- self.ctx.inputs_eos = {
- 'fleur': self.inputs.fleur,
- 'inpgen': self.inputs.inpgen,
- 'wf_parameters':
- {'points' : wf_dict.get('points', 5),
- 'step' : wf_dict.get('step', 0.02),
- 'guess' : 1.0,
- 'resources' : wf_dict.get('resources', {"num_machines": 1}),
- 'walltime_sec': wf_dict.get('walltime_sec', int(5.5*3600)),
- 'queue_name' : wf_dict.get('queue_name', ''),
- 'serial' : wf_dict.get('serial', False)
- }}
- self.ctx.wc_eos_para = Dict(dict=self.ctx.inputs_eos.get('wf_parameters'))
- self.ctx.ncalc = 1 # init
- self.get_calcs_from_groups()
- self.ctx.successful = True
- self.ctx.warnings = []
- self.ctx.labels = []
- #self.ctx.calcs_to_run = calcs
- self.ctx.ncalcs = len(self.ctx.calcs_to_run)
- print(self.ctx.ncalcs)
- print(self.ctx.ncalc)
- estimated_jobs = self.ctx.ncalc*wf_dict.get('points', 5)
- joblimit = wf_dict.get('joblimit', 90)
- self.ctx.eos_run_steps = 1
- self.ctx.eos_steps_done = 0
- self.ctx.minindex = 0
- self.ctx.maxindex = self.ctx.ncalc -1
- self.ctx.eos_max_perstep = 10000 # init
-
- if estimated_jobs >= joblimit:
- self.ctx.eos_run_steps = estimated_jobs/joblimit + 1
- self.ctx.eos_max_perstep = joblimit/wf_dict.get('points', 5)
- # TODO be carefull if is not a divisor... of joblimit
- self.ctx.maxindex = 0 # will be set later self.ctx.eos_max_perstep
-
- self.report('{} {}'.format(self.ctx.ncalc, self.ctx.eos_max_perstep))
- self.report('Estimated fleur scfs to run {}, running in {} steps.'
- ''.format(estimated_jobs, self.ctx.eos_run_steps))
-
- def get_calcs_from_groups(self):
- """
- Extract the crystal structures and parameter data nodes from the given
- groups and create calculation 'pairs' (stru, para).
- """
- wf_dict = self.inputs.wf_parameters.get_dict()
- #get all delta structure
- str_gr = wf_dict.get('struc_group', 'delta')
-
- try:
- group_pk = int(str_gr)
- except ValueError:
- group_pk = None
- group_name = str_gr
-
- if group_pk is not None:
- try:
- str_group = Group(dbgroup=group_pk)
- except NotExistent:
- str_group = None
- message = ('You have to provide a valid pk for a Group of'
- 'structures or a Group name. Wf_para key: "struc_group".'
- 'given pk= {} is not a valid group'
- '(or is your group name integer?)'.format(group_pk))
- #print(message)
- self.report(message)
- self.abort_nowait('I abort, because I have no structures to calculate ...')
- else:
- try:
- str_group = Group.get_from_string(group_name)
- except NotExistent:
- str_group = None
- message = ('You have to provide a valid pk for a Group of'
- 'structures or a Group name. Wf_para key: "struc_group".'
- 'given group name= {} is not a valid group'
- '(or is your group name integer?)'.format(group_name))
- #print(message)
- self.report(message)
- self.abort_nowait('I abort, because I have no structures to calculate ...')
-
-
- #get all delta parameters
- para_gr = wf_dict.get('para_group', 'delta')
-
- if not para_gr:
- #waring use defauls
- message = 'COMMENT: I did recieve "para_group=None" as input. I will use inpgen defaults'
- self.report(message)
-
- try:
- group_pk = int(para_gr )
- except ValueError:
- group_pk = None
- group_name = para_gr
-
- if group_pk is not None:
- try:
- para_group = Group(dbgroup=group_pk)
- except NotExistent:
- para_group = None
- message = ('ERROR: You have to provide a valid pk for a Group of'
- 'parameters or a Group name (or use None for inpgen defaults). Wf_para key: "para_group".'
- 'given pk= {} is not a valid group'
- '(or is your group name integer?)'.format(group_pk))
- #print(message)
- self.report(message)
- self.abort_nowait('ERROR: I abort, because I have no paremeters to calculate and '
- 'I guess you did not want to use the inpgen default...')
- else:
- try:
- para_group = Group.get_from_string(group_name)
- except NotExistent:
- para_group = None
- message = ('ERROR: You have to provide a valid pk for a Group of'
- 'parameters or a Group name (or use None for inpgen defaults). Wf_para key: "struc_group".'
- 'given group name= {} is not a valid group'
- '(or is your group name integer?)'.format(group_name))
- #print(message)
- self.report(message)
- self.abort_nowait('ERROR: I abort, because I have no paremeters to calculate and '
- 'I guess you did not want to use the inpgen default...')
-
- # creating calculation pairs (structure, parameters)
-
- para_nodesi = para_group.nodes
- para_nodes = []
-
- for para in para_nodesi:
- para_nodes.append(para)
- #print para_nodes
- n_para = len(para_nodes)
- stru_nodes = str_group.nodes
- n_stru = len(stru_nodes)
- if n_para != n_stru:
- message = ('COMMENT: You did not provide the same number of parameter'
- 'nodes as structure nodes. Is this wanted? npara={} nstru={}'.format(n_para, n_stru))
- self.report(message)
- calcs = []
- for struc in stru_nodes:
- para = get_paranode(struc, para_nodes)
- #if para:
- calcs.append((struc, para))
- #else:
- # calcs.append((struc))
- #pprint(calcs[:20])
- self.ctx.calcs_to_run = calcs
- self.ctx.ncalc = len(calcs)
- return
-
- def calculations_left_torun(self):
- """
- Checks if there are still some equations of states to run
- """
- calculations_left = True
- self.ctx.last_step = False
-
- if self.ctx.eos_steps_done == self.ctx.eos_run_steps:
- calculations_left = False
- if (self.ctx.eos_steps_done + 1) == self.ctx.eos_run_steps:
- self.ctx.last_step = True
-
- return calculations_left
-
-
-
- def run_eos(self):
- """
- Run the equation of states for all delta structures with their parameters
- """
- if self.ctx.last_step:
- self.ctx.maxindex = None
- else:
- self.ctx.maxindex = self.ctx.maxindex + self.ctx.eos_max_perstep
-
- self.report('Submitting eqaution of states part {} out of {}, from {} to {}'
- ''.format(self.ctx.eos_steps_done, self.ctx.eos_run_steps,
- self.ctx.minindex, self.ctx.maxindex))
-
- eos_results = {}
- inputs = self.get_inputs_eos()
-
-
- print((self.ctx.minindex))
- print((self.ctx.maxindex))
-
- for struc, para in self.ctx.calcs_to_run[self.ctx.minindex:self.ctx.maxindex]:#0:0]:#
- #print para
- formula = struc.get_formula()
- label = '|delta_wc|eos|{}'.format(formula)
- description = '|delta| fleur_eos_wc on {}'.format(formula)
- if para:
- eos_future = submit(fleur_eos_wc,
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- calc_parameters=para, inpgen=inputs['inpgen'], fleur=inputs['fleur'],
- _label=label, _description=description)
- else: # TODO: run eos_wc_simple
- eos_future = submit(fleur_eos_wc,
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- inpgen=inputs['inpgen'], fleur=inputs['fleur'],
- _label=label, _description=description)
- self.report('launching fleur_eos_wc<{}> on structure {} with parameter {}'
- ''.format(eos_future.pid, struc.pk, para.pk))
- label = formula
- self.ctx.labels.append(label)
- eos_results[label] = eos_future
-
- self.ctx.eos_steps_done = self.ctx.eos_steps_done + 1
- self.ctx.minindex = self.ctx.maxindex
-
-
- return ToContext(**eos_results)
-
- '''
- # with run
- eos_results = {}
- inputs = self.get_inputs_eos()
-
-
- for struc, para in self.ctx.calcs_to_run[:]:
- print para
- formula = struc.get_formula()
- if para:
- #print('here')
- eos_future = fleur_eos_wc.run(
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- calc_parameters=para, inpgen=inputs['inpgen'], fleur=inputs['fleur'])
- #fleur_eos_wc.run(#
- else:
- self.report('INFO: default parameters for structure {}'.format(formula))
- eos_future = fleur_eos_wc.run(
- wf_parameters=inputs['wc_eos_para'], structure=struc,
- inpgen=inputs['inpgen'], fleur=inputs['fleur'])
- #fleur_eos_wc.run(#a
- #self.report('launching fleur_eos_wc<{}> on structure {} with parameter {}'
- # ''.format(eos_future.pid, struc.pk, para.pk))
- label = formula
- self.ctx.labels.append(label)
- eos_results[label] = eos_future
-
- return ToContext(**eos_results)
- '''
-
- # To limit the troughput of 100 jobs, we create several run eos steps
- def get_inputs_eos(self):
- """
- get the inputs for a scf-cycle
- """
- inputs = {}
- # produce the inputs for a eos worklfow (collect here...)
-
- inputs['wc_eos_para'] = self.ctx.wc_eos_para
- #inputs['calc_parameters'] = self.inputs.calc_parameters
- inputs['inpgen'] = self.ctx.inputs_eos.get('inpgen')
- inputs['fleur'] = self.ctx.inputs_eos.get('fleur')
-
- return inputs
-
- def extract_results_eos(self):
- """
- extract information out of the result nodes of the the eos workchains
- ran in the step before
- """
-
- self.ctx.all_results = {}
- self.ctx.all_succ = {}
- self.ctx.eos_uuids ={}
- outstr = ('''\
- Delta calculation FLEUR {} (AiiDA wc).
-
- Crystal \t V0 \t \t B0 \t \t BP [A^3/at] \t [GPa] \t \t [--] \n
- '''.format(self.ctx.inputs_eos.get('fleur')))
- outfile = open('delta_wc.out', 'w')
- outfile.write(outstr)
- outfile.close()
- outstr = ''
- for label in self.ctx.labels:
- eos_res = self.ctx[label]
- #print(calc)
- outpara1 = eos_res.get_outputs_dict()
- #print outpara1
- try:
- outpara= outpara1['output_eos_wc_para'].get_dict()
- except KeyError:
- self.report('ERROR: Eos wc for element: {} failed. I retrieved {} '
- 'I skip the results retrieval for that element.'.format(label, eos_res))
- continue
- eos_succ = outpara.get('successful', False)
- if not eos_succ:
- #maybe do something else here (exclude point and write a warning or so, or error treatment)
- self.ctx.successful = False
-
- natoms = outpara.get('natoms', None)
- gs_vol = outpara.get('volume_gs', None)
- bm = outpara.get('bulk_modulus', None)
- #bm_u = outpara.get('bulk_modulus_units', 'GPa')
- dbm = outpara.get('bulk_deriv', None)
- if natoms:
- gs_vol_pera = gs_vol/natoms
- else:
- gs_vol_pera = gs_vol
-
- element = label.translate(None, digits) # remove all numbers from string
- self.ctx.all_results[element] = [gs_vol_pera, bm, dbm]
- self.ctx.all_succ[element] = eos_succ
- self.ctx.eos_uuids[element] = eos_res.get_inputs()[0].uuid
-
- outstr = outstr + '{} \t {:.5f} \t {:.5f} \t {:.5f} \n'.format(element, gs_vol_pera, bm, dbm)
- #write inside the loop to have at least partially results...
- #outfile = open('delta_wc.out', 'a')
- #outstr = '{} \t {:.5f} \t {:.5f} \t {:.5f} \n'.format(element, gs_vol_pera, bm, dbm)
- #outfile.write(outstr)
- #outfile.close()
- # produce a single file
- # maybe put in try(or write in a certain place where is sure that you have the permissions)
- #outfile = open('delta_wc.out', 'w')
- outfile = open('delta_wc.out', 'a') # for testing purposes
- outfile.write(outstr)
-
- outfile.close()
-
- self.ctx.outfilepath = os.path.abspath(outfile.name)
-
-
- def calculate_delta(self):
- """
- Execute here the script to calculate a delta factor
- """
- pass
-
- def return_results(self):
- """
- return the results of the calculations
- """
-
- # log some stuff in report
-
- # a text file should be written and stored as single file data and
- #parameter data node in the database
-
- #produce a single file data with all the numbers
-
- all_res = self.ctx.all_results
- bm_dic = {}
- bmd_dic = {}
- vol_dic = {}
-
- for elem,val in all_res:
- vol_dic[elem] = val[0]
- bm_dic[elem] = val[1]
- bmd_dic[elem] = val[2]
-
- outputnode_dict ={}
-
-
- outputnode_dict['workflow_name'] = self.__class__.__name__
- outputnode_dict['warnings'] = self.ctx.warnings
- outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['eos_uuids'] = self.ctx.eos_uuids
- outputnode_dict['eos_success'] = self.ctx.all_succ
- outputnode_dict['bulk_modulus'] = bm_dic
- outputnode_dict['bulk_modulus_units'] = 'GPa'
- outputnode_dict['bulk_modulus_dev'] = bmd_dic
- outputnode_dict['volumes'] = vol_dic
- outputnode_dict['volumes_units'] = 'A^3/per atom'
- outputnode_dict['delta_factor'] = {'Wien2K' : '', 'Fleur_026' : ''}
-
- #outputnode = Dict(dict=outputnode_dict)
-
- if self.ctx.successful:
- self.report('INFO: Done, delta worklfow complete')
- #print 'Done, delta worklfow complete'
- else:
- self.report('INFO: Done, but something went wrong.... Properly some '
- 'individual eos workchain failed. Check the log.')
- #print('Done, but something went wrong.... Properly some '
- # 'individual eos workchain failed. Check the log.')
-
- delta_file = SingleData.filename = self.ctx.outfilepath
-
- print(delta_file)
-
- # output must be aiida Data types.
- outnodedict = {}
- outnode = Dict(dict=outputnode_dict)
- outnodedict['results_node'] = outnode
- for label in self.ctx.labels:
- eos_res = self.ctx[label]
- #print(calc)
- outpara1 = eos_res.get_outputs_dict()
- #print outpara1
- try:
- outpara = outpara1['output_eos_wc_para']
- except KeyError:
- #self.report('ERROR: Eos wc for element: {} failed. I retrieved {} '
- # 'I skip the results retrieval for that element.'.format(label, eos_res))
- continue
- outnodedict[label] = outpara
-
- outputnode = create_delta_result_node(**outnodedict)
-
- outdict = {}
- outdict['output_delta_wc_para'] = outputnode.get('output_delta_wc_para')
- #outdict['delta_file'] = delta_file
- #print outdict
- for link_name, node in six.iteritems(outdict):
- self.out(link_name, node)
-'''
-if __name__ == "__main__":
- import argparse
-
- parser = argparse.ArgumentParser(description='SCF with FLEUR. workflow to'
- ' converge the chargedensity and optional the total energy.')
- parser.add_argument('--wf_para', type=Dict, dest='wf_parameters',
- help='The pseudopotential family', required=False)
- parser.add_argument('--structure', type=StructureData, dest='structure',
- help='The crystal structure node', required=False)
- parser.add_argument('--calc_para', type=Dict, dest='calc_parameters',
- help='Parameters for the FLEUR calculation', required=False)
- parser.add_argument('--fleurinp', type=FleurinpData, dest='fleurinp',
- help='FleurinpData from which to run the FLEUR calculation', required=False)
- parser.add_argument('--remote', type=RemoteData, dest='remote_data',
- help=('Remote Data of older FLEUR calculation, '
- 'from which files will be copied (mixing_history ...)'), required=False)
- parser.add_argument('--inpgen', type=Code, dest='inpgen',
- help='The inpgen code node to use', required=False)
- parser.add_argument('--fleur', type=Code, dest='fleur',
- help='The FLEUR code node to use', required=True)
-
- args = parser.parse_args()
- res = fleur_scf_wc.run(wf_parameters=args.wf_parameters,
- structure=args.structure,
- calc_parameters=args.calc_parameters,
- fleurinp=args.fleurinp,
- remote_data=args.remote_data,
- inpgen = args.inpgen,
- fleur=args.fleur)
-'''
-@wf
-def create_delta_result_node(**kwargs):#*args):
- """
- This is a pseudo wf, to create the rigth graph structure of AiiDA.
- This wokfunction will create the output node in the database.
- It also connects the output_node to all nodes the information commes from.
- So far it is just also parsed in as argument, because so far we are to lazy
- to put most of the code overworked from return_results in here.
-
- """
- outdict = {}
- outpara = kwargs.get('results_node', {})
- outdict['output_delta_wc_para'] = outpara.copy()
- # copy, because we rather produce the same node twice then have a circle in the database for now...
- #output_para = args[0]
- #return {'output_eos_wc_para'}
- return outdict
-
-
-def get_paranode(struc, para_nodes):
- """
- find out if a parameter node for a structure is in para_nodes
- (currently very creedy, but lists are small (100x100) but maybe reduce database accesses)
- """
-
- suuid = struc.uuid
- formula = struc.get_formula()
- element = formula.translate(None, digits)
- #print para_nodes
- for para in para_nodes:
- struc_uuid = para.get_extra('struc_uuid', None)
- para_form = para.get_extra('formula', None)
- para_ele = para.get_extra('element', None)
- if suuid == struc_uuid:
- return para
- elif formula == para_form:
- return para
- elif element == para_ele:
- return para
- elif element == para_form:
- return para
- else:
- pass
- #Do something else (test if parameters for a certain element are there)
- #....
- # we found no parameter node for the given structure therefore return none
- return None
-
-def write_delta_file(result_dict):
- pass
diff --git a/aiida_fleur/workflows/dmi.py b/aiida_fleur/workflows/dmi.py
index 4dc7d1448..9a98361a1 100644
--- a/aiida_fleur/workflows/dmi.py
+++ b/aiida_fleur/workflows/dmi.py
@@ -35,7 +35,7 @@
from aiida_fleur.workflows.scf import FleurScfWorkChain
from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
from aiida_fleur.workflows.base_fleur import FleurBaseWorkChain
-
+from aiida_fleur.common.constants import HTR_TO_EV
from aiida_fleur.data.fleurinp import FleurinpData
@@ -58,7 +58,7 @@ class FleurDMIWorkChain(WorkChain):
'environment_variables': {}
}
- _wf_default = {
+ _default_wf_para = {
'serial': False,
'only_even_MPI': False,
'beta': {
@@ -75,7 +75,7 @@ class FleurDMIWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurDMIWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
spec.input('fleur', valid_type=Code, required=True)
@@ -124,7 +124,7 @@ def start(self):
self.ctx.q_vectors = []
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -493,7 +493,6 @@ def get_results(self):
"""
Generates results of the workchain.
"""
- htr_to_ev = 27.21138602
t_energydict = []
mae_thetas = []
mae_phis = []
@@ -531,7 +530,7 @@ def get_results(self):
if e_u == 'Htr' or 'htr':
for labels, energies in t_energydict.items():
- t_energydict[labels] = energies * htr_to_ev
+ t_energydict[labels] = energies * HTR_TO_EV
except AttributeError:
message = ('Did not manage to read evSum or energy units after FT calculation.')
self.control_end_wc(message)
diff --git a/aiida_fleur/workflows/dos.py b/aiida_fleur/workflows/dos.py
index 88508c749..ce6ee4229 100644
--- a/aiida_fleur/workflows/dos.py
+++ b/aiida_fleur/workflows/dos.py
@@ -58,11 +58,11 @@ class fleur_dos_wc(WorkChain):
@classmethod
def define(cls, spec):
- super(fleur_dos_wc, cls).define(spec)
- spec.input('wf_parameters', valid_type=Dict, required=False, default=Dict(dict=cls._default_wf_para))
+ super().define(spec)
+ spec.input('wf_parameters', valid_type=Dict, required=False, default=lambda: Dict(dict=cls._default_wf_para))
spec.input('calc_parameters', valid_type=Dict, required=False)
spec.input('settings', valid_type=Dict, required=False)
- spec.input('options', valid_type=Dict, required=False, default=Dict(dict=cls._default_options))
+ spec.input('options', valid_type=Dict, required=False, default=lambda: Dict(dict=cls._default_options))
spec.input('fleurinp', valid_type=FleurinpData, required=False)
# TODO ggf run convergence first
spec.input('remote_data', valid_type=RemoteData, required=False)
diff --git a/aiida_fleur/workflows/eos.py b/aiida_fleur/workflows/eos.py
index fa97dbfe0..0a47eba02 100644
--- a/aiida_fleur/workflows/eos.py
+++ b/aiida_fleur/workflows/eos.py
@@ -32,6 +32,7 @@
from aiida_fleur.tools.StructureData_util import rescale, rescale_nowf, is_structure
from aiida_fleur.workflows.scf import FleurScfWorkChain
from aiida_fleur.tools.common_fleur_wf_util import check_eos_energies
+from aiida_fleur.common.constants import HTR_TO_EV
class FleurEosWorkChain(WorkChain):
@@ -54,11 +55,12 @@ class FleurEosWorkChain(WorkChain):
_workflowversion = '0.4.0'
- _wf_default = {'points': 9, 'step': 0.002, 'guess': 1.00}
+ _default_wf_para = {'points': 9, 'step': 0.002, 'guess': 1.00}
+ _default_options = FleurScfWorkChain._default_options
@classmethod
def define(cls, spec):
- super(FleurEosWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf', exclude=(
'structure',
'remote_data',
@@ -100,7 +102,7 @@ def start(self):
# TODO get all successful from convergence, if all True this
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = self._wf_default
+ wf_default = self._default_wf_para
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -190,7 +192,6 @@ def return_results(self):
vol_peratom_success = []
outnodedict = {}
natoms = len(self.inputs.structure.sites)
- htr_to_ev = 27.21138602
e_u = 'eV'
dis_u = 'me/bohr^3'
for label in self.ctx.labels:
@@ -220,7 +221,7 @@ def return_results(self):
t_e = outpara.get('total_energy', float('nan'))
e_u = outpara.get('total_energy_units', 'eV')
if e_u == 'Htr' or 'htr':
- t_e = t_e * htr_to_ev
+ t_e = t_e * HTR_TO_EV
dis = outpara.get('distance_charge', float('nan'))
dis_u = outpara.get('distance_charge_units', 'me/bohr^3')
t_energylist.append(t_e)
diff --git a/aiida_fleur/workflows/initial_cls.py b/aiida_fleur/workflows/initial_cls.py
index 6a69161a9..b6c373da5 100644
--- a/aiida_fleur/workflows/initial_cls.py
+++ b/aiida_fleur/workflows/initial_cls.py
@@ -107,8 +107,8 @@ class fleur_initial_cls_wc(WorkChain):
@classmethod
def define(cls, spec):
- super(fleur_initial_cls_wc, cls).define(spec)
- spec.input('wf_parameters', valid_type=Dict, required=False, default=Dict(dict=cls._default_wf_para))
+ super().define(spec)
+ spec.input('wf_parameters', valid_type=Dict, required=False, default=lambda: Dict(dict=cls._default_wf_para))
spec.input('fleurinp', valid_type=FleurinpData, required=False)
spec.input('fleur', valid_type=Code, required=True)
spec.input('inpgen', valid_type=Code, required=False)
@@ -163,6 +163,7 @@ def check_input(self):
self.ctx.bandgaps = {}
self.ctx.atomtypes = {}
# set values, or defaults for Wf_para
+ # 'wf_parameters' always there
wf_dict = self.inputs.wf_parameters.get_dict()
default = self._default_wf_para
@@ -174,7 +175,7 @@ def check_input(self):
self.ctx.relax_para = wf_dict.get('relax_para', default.get('dos_para'))
defaultoptions = self._default_options
- if self.inputs.options:
+ if 'options' in self.inputs:
options = self.inputs.options.get_dict()
else:
options = defaultoptions
@@ -774,34 +775,47 @@ def return_results(self):
if self.ctx.errors:
self.ctx.warnings.append(self.ctx.errors)
+ material = list(efermi.keys())
+ if material:
+ material = material[0]
+ fermi_energy = list(efermi.values())
+ if fermi_energy:
+ fermi_energy = fermi_energy[0]
+ total_energy = list(tE.values())
+ if total_energy:
+ total_energy = total_energy[0]
+ bandgap = list(gap.values())
+ if bandgap:
+ bandgap = bandgap[0]
+
outputnode_dict = {}
outputnode_dict['workflow_name'] = self.__class__.__name__
outputnode_dict['workflow_version'] = self._workflowversion
outputnode_dict['warnings'] = self.ctx.warnings
outputnode_dict['successful'] = self.ctx.successful
- outputnode_dict['material'] = list(efermi.keys())[0]
+ outputnode_dict['material'] = material
outputnode_dict['corelevel_energies'] = cl
outputnode_dict['corelevel_energies_units'] = 'htr' #'eV'
outputnode_dict['reference_corelevel_energies'] = ref_cl
outputnode_dict['reference_corelevel_energies_units'] = 'htr' #'eV'
outputnode_dict['reference_fermi_energy'] = list(ref_efermi.values())
outputnode_dict['reference_fermi_energy_des'] = list(ref_efermi.keys())
- outputnode_dict['fermi_energy'] = list(efermi.values())[0]
+ outputnode_dict['fermi_energy'] = efermi
outputnode_dict['fermi_energy_units'] = 'htr'
outputnode_dict['corelevelshifts'] = cls
outputnode_dict['corelevelshifts_units'] = 'htr'
outputnode_dict['binding_energy_convention'] = 'negativ'
#outputnode_dict['coresetup'] = []#cls
#outputnode_dict['reference_coresetup'] = []#cls
- outputnode_dict['bandgap'] = list(gap.values())[0]
+ outputnode_dict['bandgap'] = bandgap
outputnode_dict['bandgap_units'] = 'htr'
outputnode_dict['reference_bandgaps'] = list(ref_gap.values())
outputnode_dict['reference_bandgaps_des'] = list(ref_gap.keys())
outputnode_dict['atomtypes'] = at
outputnode_dict['formation_energy'] = formE
outputnode_dict['formation_energy_units'] = 'eV/atom'
- outputnode_dict['total_energy'] = list(tE.values())[0]
+ outputnode_dict['total_energy'] = total_energy
outputnode_dict['total_energy_units'] = 'eV'
outputnode_dict['total_energy_ref'] = list(tE_ref.values())
outputnode_dict['total_energy_ref_des'] = list(tE_ref.keys())
@@ -926,12 +940,14 @@ def extract_results(calcs):
for calc in calcs:
#print(calc)
try:
- calc_uuids.append(calc.get_outgoing().get_node_by_label('output_scf_wc_para').get_dict()['last_calc_uuid'])
+ calc_uuid = calc.get_outgoing().get_node_by_label('output_scf_wc_para').get_dict()['last_calc_uuid']
except (NotExistent, MultipleObjectsError, ValueError, TypeError, KeyError): #TODO which error
logmsg = ('ERROR: No output_scf_wc_para node found or no "last_calc_uuid" '
'key in it for calculation: {}'.format(calc))
log.append(logmsg)
continue
+ if calc_uuid is not None:
+ calc_uuids.append(calc_uuid)
#calc_uuids.append(calc['output_scf_wc_para'].get_dict()['last_calc_uuid'])
all_corelevels = {}
diff --git a/aiida_fleur/workflows/mae.py b/aiida_fleur/workflows/mae.py
index e73c96f65..befb8ba6f 100644
--- a/aiida_fleur/workflows/mae.py
+++ b/aiida_fleur/workflows/mae.py
@@ -33,6 +33,7 @@
from aiida_fleur.workflows.base_fleur import FleurBaseWorkChain
from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
from aiida_fleur.data.fleurinp import FleurinpData
+from aiida_fleur.common.constants import HTR_TO_EV
class FleurMaeWorkChain(WorkChain):
@@ -54,7 +55,7 @@ class FleurMaeWorkChain(WorkChain):
'environment_variables': {}
}
- _wf_default = {
+ _default_wf_para = {
'sqa_ref': [0.7, 0.7],
'use_soc_ref': False,
'sqas_theta': [0.0, 1.57079, 1.57079],
@@ -67,7 +68,7 @@ class FleurMaeWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurMaeWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
spec.input('fleur', valid_type=Code, required=True)
@@ -115,7 +116,7 @@ def start(self):
self.ctx.fleuroutuuid = None
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -449,7 +450,6 @@ def get_results(self):
t_energydict = []
mae_thetas = []
mae_phis = []
- htr_to_ev = 27.21138602
fleur_output_uuid = None
try:
@@ -476,7 +476,7 @@ def get_results(self):
minenergy = min(t_energydict)
if e_u == 'Htr' or 'htr':
- t_energydict = [htr_to_ev * (x - minenergy) for x in t_energydict]
+ t_energydict = [HTR_TO_EV * (x - minenergy) for x in t_energydict]
else:
t_energydict = [(x - minenergy) for x in t_energydict]
diff --git a/aiida_fleur/workflows/mae_conv.py b/aiida_fleur/workflows/mae_conv.py
index 6304b952d..220a6bb75 100644
--- a/aiida_fleur/workflows/mae_conv.py
+++ b/aiida_fleur/workflows/mae_conv.py
@@ -24,6 +24,7 @@
from aiida.common import AttributeDict
from aiida_fleur.workflows.scf import FleurScfWorkChain
+from aiida_fleur.common.constants import HTR_TO_EV
class FleurMaeConvWorkChain(WorkChain):
@@ -33,11 +34,22 @@ class FleurMaeConvWorkChain(WorkChain):
_workflowversion = '0.2.0'
- _wf_default = {'sqas': {'label': [0.0, 0.0]}, 'soc_off': []}
+ _default_wf_para = {'sqas': {'label': [0.0, 0.0]}, 'soc_off': []}
+ _default_options = {
+ 'resources': {
+ 'num_machines': 1,
+ 'num_mpiprocs_per_machine': 1
+ },
+ 'max_wallclock_seconds': 6 * 60 * 60,
+ 'queue_name': '',
+ 'custom_scheduler_commands': '',
+ 'import_sys_environment': False,
+ 'environment_variables': {}
+ }
@classmethod
def define(cls, spec):
- super(FleurMaeConvWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
@@ -67,7 +79,7 @@ def start(self):
self.ctx.mae_phis = []
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -146,7 +158,6 @@ def get_results(self):
t_energydict = {}
original_t_energydict = {}
outnodedict = {}
- htr_to_ev = 27.21138602
for label in six.iterkeys(self.ctx.wf_dict['sqas']):
calc = self.ctx[label]
@@ -172,7 +183,7 @@ def get_results(self):
continue
e_u = outpara.get('total_energy_units', 'Htr')
if e_u == 'Htr' or 'htr':
- t_e = t_e * htr_to_ev
+ t_e = t_e * HTR_TO_EV
t_energydict[label] = t_e
if t_energydict:
diff --git a/aiida_fleur/workflows/optimize_para.py b/aiida_fleur/workflows/optimize_para.py
index 901bd7b42..c6c5a2032 100644
--- a/aiida_fleur/workflows/optimize_para.py
+++ b/aiida_fleur/workflows/optimize_para.py
@@ -50,17 +50,19 @@ class fleur_optimize_parameters_wc(WorkChain):
_workflowversion = '0.1.0'
+ _default_wf_para = {}
+
def __init__(self, *args, **kwargs):
- super(fleur_optimize_parameters_wc, self).__init__(*args, **kwargs)
+ super().__init__(*args, **kwargs)
@classmethod
def define(cls, spec):
- super(fleur_optimize_parameters_wc, cls).define(spec)
+ super().define(spec)
spec.input(
'wf_parameters',
valid_type=Dict,
required=False,
- default=Dict(
+ default=lambda: Dict(
dict={
'resources': {
'num_machines': 1
diff --git a/aiida_fleur/workflows/relax.py b/aiida_fleur/workflows/relax.py
index ea81d67ec..1cdd36bb6 100644
--- a/aiida_fleur/workflows/relax.py
+++ b/aiida_fleur/workflows/relax.py
@@ -27,7 +27,7 @@
from aiida_fleur.workflows.scf import FleurScfWorkChain
from aiida_fleur.calculation.fleur import FleurCalculation as FleurCalc
-from aiida_fleur.common.constants import bohr_a
+from aiida_fleur.common.constants import BOHR_A
from aiida_fleur.tools.StructureData_util import break_symmetry_wf
@@ -36,21 +36,25 @@ class FleurRelaxWorkChain(WorkChain):
This workflow performs structure optimization.
"""
- _workflowversion = '0.2.2'
+ _workflowversion = '0.3.0'
- _wf_default = {
+ _default_wf_para = {
'relax_iter': 5, # Stop if not converged after so many relaxation steps
'film_distance_relaxation': False, # Do not relax the z coordinates
'force_criterion': 0.001, # Converge the force until lower this value in atomic units
'run_final_scf': False, # Run a final scf on the final relaxed structure
'break_symmetry': False, # Break the symmetry for the relaxation each atom own type
'change_mixing_criterion': 0.025, # After the force is smaller switch mixing scheme
- 'atoms_off': [] # Species to be switched off, '49' is reserved
+ 'atoms_off': [], # Species to be switched off, '49' is reserved
+ 'relaxation_type': 'atoms' # others include None and maybe in the future volume
+ # None would run an scf only
}
+ _default_options = FleurScfWorkChain._default_options
+
@classmethod
def define(cls, spec):
- super(FleurRelaxWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.expose_inputs(FleurScfWorkChain,
namespace='final_scf',
@@ -62,13 +66,11 @@ def define(cls, spec):
spec.outline(
cls.start,
- cls.converge_scf,
- cls.check_failure,
- while_(cls.condition)(
+ if_(cls.should_relax)(cls.converge_scf, cls.check_failure, while_(cls.condition)(
cls.generate_new_fleurinp,
cls.converge_scf,
cls.check_failure,
- ),
+ )),
cls.get_results_relax,
if_(cls.should_run_final_scf)(cls.run_final_scf, cls.get_results_final_scf),
cls.return_results,
@@ -111,9 +113,10 @@ def start(self):
self.ctx.switch_bfgs = False # Bool if BFGS should be switched on
self.ctx.scf_res = None # Last scf results
self.ctx.final_structure = None # The optimized structure
+ self.ctx.total_magnetic_moment = None
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -166,6 +169,19 @@ def start(self):
self.report('Error: Wrong input: inpgen missing for final scf.')
return self.exit_codes.ERROR_INPGEN_MISSING
+ def should_relax(self):
+ """
+ Should we run a relaxation or only a final scf
+ This allows to call the workchain to run an scf only and makes
+ logic of other higher workflows a lot easier
+ """
+ relaxtype = self.ctx.wf_dict.get('relaxation_type', 'atoms')
+ if relaxtype is None:
+ self.ctx.reached_relax = True
+ return False
+ else:
+ return True
+
def converge_scf(self):
"""
Submits :class:`aiida_fleur.workflows.scf.FleurScfWorkChain`.
@@ -433,6 +449,24 @@ def get_results_relax(self):
Creates a new structure data node which is an
optimized structure.
"""
+
+ if self.ctx.wf_dict.get('relaxation_type', 'atoms') is None:
+ input_scf = AttributeDict(self.exposed_inputs(FleurScfWorkChain, namespace='scf'))
+ if 'structure' in input_scf:
+ structure = input_scf.structure
+ elif 'fleurinp' in input_scf:
+ structure = input_scf.fleurinp.get_structuredata_ncf()
+ else:
+ pass
+ self.ctx.final_structure = structure
+ self.ctx.total_energy_last = None #total_energy
+ self.ctx.total_energy_units = None #total_energy_units
+ self.ctx.final_cell = structure.cell
+ self.ctx.final_atom_positions = None #atom_positions
+ self.ctx.atomtype_info = None
+
+ return
+
try:
relax_out = self.ctx.scf_res.outputs.last_fleur_calc_output
except NotExistent:
@@ -446,6 +480,7 @@ def get_results_relax(self):
film = relax_out['film']
total_energy = relax_out['energy']
total_energy_units = relax_out['energy_units']
+ atomtype_info = relax_out['relax_atomtype_info']
except KeyError:
return self.exit_codes.ERROR_NO_RELAX_OUTPUT
@@ -453,6 +488,7 @@ def get_results_relax(self):
self.ctx.total_energy_units = total_energy_units
self.ctx.final_cell = cell
self.ctx.final_atom_positions = atom_positions
+ self.ctx.atomtype_info = atomtype_info
if film == 'True':
self.ctx.pbc = (True, True, False)
@@ -460,17 +496,24 @@ def get_results_relax(self):
self.ctx.pbc = (True, True, True)
# we build the structure here, that way we can run an scf afterwards
+ # construct it in a way which preserves the species information from the initial input structure
if self.ctx.final_cell:
- np_cell = np.array(self.ctx.final_cell) * bohr_a
+ np_cell = np.array(self.ctx.final_cell) * BOHR_A
structure = StructureData(cell=np_cell.tolist())
-
- for atom in self.ctx.final_atom_positions:
- np_pos = np.array(atom[1:])
+ #self.report('############ {}'.format(atomtype_info))
+ for i, atom in enumerate(self.ctx.final_atom_positions):
+ species_name = atomtype_info[i][0]
+ element = atomtype_info[i][1]
+ np_pos = np.array(atom)
pos_abs = np_pos @ np_cell
if self.ctx.pbc == (True, True, True):
- structure.append_atom(position=(pos_abs[0], pos_abs[1], pos_abs[2]), symbols=atom[0])
+ structure.append_atom(position=(pos_abs[0], pos_abs[1], pos_abs[2]),
+ symbols=element,
+ name=species_name)
else: # assume z-direction is orthogonal to xy
- structure.append_atom(position=(pos_abs[0], pos_abs[1], atom[3] * bohr_a), symbols=atom[0])
+ structure.append_atom(position=(pos_abs[0], pos_abs[1], atom[3] * BOHR_A),
+ symbols=element,
+ name=species_name)
structure.pbc = self.ctx.pbc
self.ctx.final_structure = structure
@@ -496,6 +539,17 @@ def get_results_final_scf(self):
self.ctx.total_energy_last = total_energy
self.ctx.total_energy_units = total_energy_units
+ if self.ctx.wf_dict.get('relaxation_type', 'atoms') is None:
+ # we need this for run through
+ self.ctx.scf_res = self.ctx.scf_final_res
+
+ #if jspin ==2
+ try:
+ total_mag = scf_out_d['total_magnetic_moment_cell']
+ self.ctx.total_magnetic_moment = total_mag
+ except KeyError:
+ self.report('ERROR: Could not parse total magnetic moment cell of final scf run')
+
def return_results(self):
"""
This function stores results of the workchain into the output nodes.
@@ -514,7 +568,9 @@ def return_results(self):
'force_iter_done': self.ctx.loop_count,
# uuids in the output are bad for caching should be avoided,
# instead better return the node.
- 'last_scf_wc_uuid': self.ctx.scf_res.uuid
+ 'last_scf_wc_uuid': self.ctx.scf_res.uuid,
+ 'total_magnetic_moment_cell': self.ctx.total_magnetic_moment,
+ 'total_magnetic_moment_cell_units': 'muBohr'
}
outnode = Dict(dict=out)
diff --git a/aiida_fleur/workflows/scf.py b/aiida_fleur/workflows/scf.py
index 70e0d4d2c..f48eebd09 100644
--- a/aiida_fleur/workflows/scf.py
+++ b/aiida_fleur/workflows/scf.py
@@ -60,8 +60,8 @@ class FleurScfWorkChain(WorkChain):
like Success, last result node, list with convergence behavior
"""
- _workflowversion = '0.4.2'
- _wf_default = {
+ _workflowversion = '0.4.3'
+ _default_wf_para = {
'fleur_runmax': 4,
'density_converged': 0.00002,
'energy_converged': 0.002,
@@ -97,7 +97,7 @@ class FleurScfWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurScfWorkChain, cls).define(spec)
+ super().define(spec)
spec.input('fleur', valid_type=Code, required=True)
spec.input('inpgen', valid_type=Code, required=False)
spec.input('wf_parameters', valid_type=Dict, required=False)
@@ -107,7 +107,7 @@ def define(cls, spec):
spec.input('remote_data', valid_type=RemoteData, required=False)
spec.input('options', valid_type=Dict, required=False)
spec.input('settings', valid_type=Dict, required=False)
-
+ spec.input('settings_inpgen', valid_type=Dict, required=False)
spec.outline(cls.start, cls.validate_input,
if_(cls.fleurinpgen_needed)(cls.run_fleurinpgen), cls.run_fleur, cls.inspect_fleur, cls.get_res,
while_(cls.condition)(cls.run_fleur, cls.inspect_fleur, cls.get_res), cls.return_results)
@@ -144,7 +144,7 @@ def start(self):
self.ctx.abort = False
self.ctx.reached_conv = True
- wf_default = self._wf_default
+ wf_default = self._default_wf_para
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -155,12 +155,33 @@ def start(self):
self.ctx.wf_dict = wf_dict
self.ctx.serial = self.ctx.wf_dict.get('serial', False)
+ fleur = self.inputs.fleur
+ fleur_extras = fleur.extras
+ inpgen_extras = None
+ if 'inpgen' in self.inputs:
+ inpgen = self.inputs.inpgen
+ inpgen_extras = inpgen.extras
+
+ defaultoptions = self._default_options.copy()
+ user_options = {}
+ if 'options' in self.inputs:
+ user_options = self.inputs.options.get_dict()
+
+ # extend options by code defaults given in code extras
+ # Maybe do full recursive merge
+ if 'queue_defaults' in fleur_extras:
+ qd = fleur_extras['queue_defaults']
+ queue = user_options.get('queue', 'default')
+ defaults_queue = qd.get(queue, {})
+ for key, val in defaultoptions.items():
+ defaultoptions[key] = defaults_queue.get(key, val)
- defaultoptions = self._default_options
if 'options' in self.inputs:
- options = self.inputs.options.get_dict()
+ options = user_options
else:
options = defaultoptions
+ # we use the same options for both codes, inpgen resources get overridden
+ # and queue does not matter in case of direct scheduler
# extend options given by user using defaults
for key, val in six.iteritems(defaultoptions):
@@ -201,7 +222,7 @@ def validate_input(self):
"""
extra_keys = []
for key in self.ctx.wf_dict.keys():
- if key not in self._wf_default.keys():
+ if key not in self._default_wf_para.keys():
extra_keys.append(key)
if extra_keys:
error = 'ERROR: input wf_parameters for SCF contains extra keys: {}'.format(extra_keys)
@@ -304,6 +325,11 @@ def run_fleurinpgen(self):
else:
params = None
+ if 'settings_inpgen' in self.inputs:
+ settings = self.inputs.settings_inpgen
+ else:
+ settings = None
+
# If given kpt_dist has prio over given calc_parameters
kpt_dist = self.ctx.wf_dict.get('kpoints_distance', None)
if kpt_dist is not None:
@@ -330,7 +356,13 @@ def run_fleurinpgen(self):
'queue_name': self.ctx.options.get('queue_name', '')
}
- inputs_build = get_inputs_inpgen(structure, inpgencode, options, label, description, params=params)
+ inputs_build = get_inputs_inpgen(structure,
+ inpgencode,
+ options,
+ label,
+ description,
+ settings=settings,
+ params=params)
# Launch inpgen
self.report('INFO: run inpgen')
diff --git a/aiida_fleur/workflows/ssdisp.py b/aiida_fleur/workflows/ssdisp.py
index a5ec7fd46..9decd146e 100644
--- a/aiida_fleur/workflows/ssdisp.py
+++ b/aiida_fleur/workflows/ssdisp.py
@@ -33,7 +33,7 @@
from aiida_fleur.workflows.scf import FleurScfWorkChain
from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
from aiida_fleur.workflows.base_fleur import FleurBaseWorkChain
-
+from aiida_fleur.common.constants import HTR_TO_EV
from aiida_fleur.data.fleurinp import FleurinpData
@@ -56,7 +56,7 @@ class FleurSSDispWorkChain(WorkChain):
'environment_variables': {}
}
- _wf_default = {
+ _default_wf_para = {
'beta': {
'all': 1.57079
},
@@ -70,7 +70,7 @@ class FleurSSDispWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurSSDispWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
spec.input('fleur', valid_type=Code, required=True)
@@ -113,7 +113,7 @@ def start(self):
self.ctx.energy_dict = []
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
@@ -454,7 +454,6 @@ def get_results(self):
Generates results of the workchain.
"""
t_energydict = []
- htr_to_ev = 27.21138602
try:
calculation = self.ctx.f_t
if not calculation.is_finished_ok:
@@ -476,7 +475,7 @@ def get_results(self):
minenergy = min(t_energydict)
if e_u == 'Htr' or 'htr':
- t_energydict = [htr_to_ev * (x - minenergy) for x in t_energydict]
+ t_energydict = [HTR_TO_EV * (x - minenergy) for x in t_energydict]
else:
t_energydict = [(x - minenergy) for x in t_energydict]
diff --git a/aiida_fleur/workflows/ssdisp_conv.py b/aiida_fleur/workflows/ssdisp_conv.py
index 7efab8441..889ea388f 100644
--- a/aiida_fleur/workflows/ssdisp_conv.py
+++ b/aiida_fleur/workflows/ssdisp_conv.py
@@ -33,7 +33,7 @@ class FleurSSDispConvWorkChain(WorkChain):
_workflowversion = '0.2.0'
- _wf_default = {
+ _default_wf_para = {
'beta': {
'all': 1.57079
},
@@ -46,7 +46,7 @@ class FleurSSDispConvWorkChain(WorkChain):
@classmethod
def define(cls, spec):
- super(FleurSSDispConvWorkChain, cls).define(spec)
+ super().define(spec)
spec.expose_inputs(FleurScfWorkChain, namespace='scf')
spec.input('wf_parameters', valid_type=Dict, required=False)
@@ -76,7 +76,7 @@ def start(self):
self.ctx.energy_dict = []
# initialize the dictionary using defaults if no wf paramters are given
- wf_default = copy.deepcopy(self._wf_default)
+ wf_default = copy.deepcopy(self._default_wf_para)
if 'wf_parameters' in self.inputs:
wf_dict = self.inputs.wf_parameters.get_dict()
else:
diff --git a/docs/source/module_guide/code.rst b/docs/source/module_guide/code.rst
index 0d2c27519..cc1d9e841 100644
--- a/docs/source/module_guide/code.rst
+++ b/docs/source/module_guide/code.rst
@@ -59,10 +59,10 @@ SCF: Fleur-Scf WorkChain
.. automodule:: aiida_fleur.workflows.scf
:members:
-Band: Bandstructure WorkChain
-------------------------------
+BandDos: Bandstructure WorkChain
+--------------------------------
-.. automodule:: aiida_fleur.workflows.band
+.. automodule:: aiida_fleur.workflows.banddos
:members:
DOS: Density of states WorkChain
@@ -95,12 +95,6 @@ corehole: Performance of coreholes calculations
.. automodule:: aiida_fleur.workflows.corehole
:members:
-delta: Calculates a Delta Factor
---------------------------------
-
-.. automodule:: aiida_fleur.workflows.delta
- :members:
-
MAE: Force-theorem calculation of magnetic anisotropy energies
----------------------------------------------------------------
diff --git a/docs/source/user_guide/data/fleurinp_data.rst b/docs/source/user_guide/data/fleurinp_data.rst
index ac5a8fdaf..5a17e4271 100644
--- a/docs/source/user_guide/data/fleurinp_data.rst
+++ b/docs/source/user_guide/data/fleurinp_data.rst
@@ -111,11 +111,10 @@ User Methods
* :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.get_parameterdata()` - A CalcFunction
that extracts a :py:class:`~aiida.orm.Dict` node
containing FLAPW parameters. This node can be used as an input for inpgen.
- * :py:func:`~aiida_fleur.data.fleurinp.FleurinpData.set_kpointsdata()` -
- A CalcFunction that writes kpoints
- of a :py:class:`~aiida.orm.KpointsData` node in the
- inp.xml file returns a new
- :py:class:`~aiida_fleur.data.fleurinp.FleurinpData` instance. It replaces old kpoints.
+ * :py:func:`~aiida_fleur.data.fleurinpmodifier.set_kpointsdata_f()` -
+ A Function of fleurmodifier used to writes kpoints
+ of a :py:class:`~aiida.orm.KpointsData` node to the
+ inp.xml file. It replaces old kpoints.
.. _setting_labels:
diff --git a/docs/source/user_guide/workflows/dos_band_wc.rst b/docs/source/user_guide/workflows/dos_band_wc.rst
index 290d85573..9aee76c80 100644
--- a/docs/source/user_guide/workflows/dos_band_wc.rst
+++ b/docs/source/user_guide/workflows/dos_band_wc.rst
@@ -9,8 +9,8 @@ Fleur dos/band workflows
These are two seperate workflows which are pretty similar so we treat them here together
-* **Class**: :py:class:`~aiida_fleur.workflows.dos.fleur_dos_wc` and :py:class:`~aiida_fleur.workflows.band.FleurBandWorkChain`
-* **String to pass to the** :py:func:`~aiida.plugins.WorkflowFactory`: ``fleur.dos``, ``fleur.band``
+* **Class**: :py:class:`~aiida_fleur.workflows.dos.fleur_dos_wc` and :py:class:`~aiida_fleur.workflows.banddos.FleurBandDosWorkChain`
+* **String to pass to the** :py:func:`~aiida.plugins.WorkflowFactory`: ``fleur.dos``, ``fleur.banddos``
* **Workflow type**: Workflow (lv 1)
* **Aim**: Calculate a density of states. Calculate a Band structure.
* **Compuational demand**: 1 ``Fleur Job calculation``
@@ -28,9 +28,9 @@ Import Example:
#or
WorkflowFactory('fleur.dos')
- from aiida_fleur.workflows.band import FleurBandWorkChain
+ from aiida_fleur.workflows.banddos import FleurBandDosWorkChain
#or
- WorkflowFactory('fleur.band')
+ WorkflowFactory('fleur.banddos')
Description/Purpose
^^^^^^^^^^^^^^^^^^^
@@ -38,11 +38,11 @@ Description/Purpose
Calculates an Density of states (DOS) ontop of a given Fleur calculation (converged or not).
- Band:
+ BandDos:
Calculates an electronic band structure ontop of a given Fleur calculation (converged or not).
- In the future we plan to add the posibility to converge a calculation before, and choose the kpaths automatic.
+ In the future we plan to add the possibility to converge a calculation before, and choose the kpaths automatic.
This version should be able start simply from a crystal structure.
Each of these workflows prepares/chances the Fleur input and manages one Fleur calculation.
diff --git a/docs/source/user_guide/workflows/wc_index.rst b/docs/source/user_guide/workflows/wc_index.rst
index df1da81f6..54f136214 100644
--- a/docs/source/user_guide/workflows/wc_index.rst
+++ b/docs/source/user_guide/workflows/wc_index.rst
@@ -10,7 +10,7 @@ Inputs
''''''
There is always a ``wf_parameters``:
-:py:class:`~aiida.orm.Dict` node for controlling the workflow behaviour.
+:py:class:`~aiida.orm.Dict` node for controlling the workflow behavior.
It contains all the parameters related to physical aspects of the
workchain and its content vary between different workchains.
diff --git a/setup.json b/setup.json
index 85750bc6a..166e27385 100644
--- a/setup.json
+++ b/setup.json
@@ -1,5 +1,5 @@
{
- "version": "1.1.2",
+ "version": "1.1.3",
"name": "aiida-fleur",
"url": "https://github.com/JuDFTteam/aiida-fleur",
"license": "MIT License, see LICENSE.txt file.",
@@ -30,9 +30,9 @@
"aiida-core>=1.3.0,<2.0.0",
"lxml >= 3.6.4",
"pytest-cov >= 2.5.0",
- "numpy>=1.16.4,<1.18.0",
+ "numpy>=1.16.4,<1.20.0",
"sympy",
- "masci-tools==0.3.12-dev4",
+ "masci-tools>=0.3.12-dev4",
"future",
"ase",
"pymatgen",
@@ -50,14 +50,15 @@
],
"pre-commit": [
"pre-commit>=2.6.0",
- "yapf==0.30.0",
- "pylint==2.5.2"
+ "yapf~=0.30",
+ "pylint>=2.5"
],
"testing" : [
"pytest>=2.9",
"pytest-timeout",
"pytest-cov>= 2.5.0",
- "pgtest"
+ "pgtest",
+ "pytest-regressions>=1.0"
]
},
"entry_points": {
@@ -76,7 +77,6 @@
"aiida.workflows": [
"fleur.scf = aiida_fleur.workflows.scf:FleurScfWorkChain",
"fleur.dos = aiida_fleur.workflows.dos:fleur_dos_wc",
- "fleur.band = aiida_fleur.workflows.band:FleurBandWorkChain",
"fleur.banddos = aiida_fleur.workflows.banddos:FleurBandDosWorkChain",
"fleur.eos = aiida_fleur.workflows.eos:FleurEosWorkChain",
"fleur.init_cls = aiida_fleur.workflows.initial_cls:fleur_initial_cls_wc",
@@ -90,6 +90,9 @@
"fleur.create_magnetic = aiida_fleur.workflows.create_magnetic_film:FleurCreateMagneticWorkChain",
"fleur.base_relax = aiida_fleur.workflows.base_relax:FleurBaseRelaxWorkChain",
"fleur.base = aiida_fleur.workflows.base_fleur:FleurBaseWorkChain"
+ ],
+ "console_scripts": [
+ "aiida-fleur = aiida_fleur.cmdline:cmd_root"
]
}
}
diff --git a/setup.py b/setup.py
index 73ebd7f5a..d02ae26aa 100644
--- a/setup.py
+++ b/setup.py
@@ -1,7 +1,6 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
-from __future__ import absolute_import
from setuptools import setup, find_packages
import json
@@ -10,4 +9,12 @@
# such that it can be discovered automatically
with open('setup.json', 'r') as info:
kwargs = json.load(info)
- setup(packages=find_packages(exclude='aiida'), **kwargs)
+ setup(
+ packages=find_packages(exclude=['tests*']),
+ # this doesn't work when placed in setup.json (something to do with str type)
+ package_data={
+ '': ['*'],
+ },
+ long_description=open('README.md').read(),
+ long_description_content_type='text/markdown',
+ **kwargs)
diff --git a/tests/.aiida/config.json b/tests/.aiida/config.json
deleted file mode 100644
index d74fb51db..000000000
--- a/tests/.aiida/config.json
+++ /dev/null
@@ -1,7 +0,0 @@
-{
- "CONFIG_VERSION": {
- "CURRENT": 3,
- "OLDEST_COMPATIBLE": 3
- },
- "profiles": {}
-}
diff --git a/tests/.coveragerc b/tests/.coveragerc
deleted file mode 100644
index eb3500f32..000000000
--- a/tests/.coveragerc
+++ /dev/null
@@ -1,6 +0,0 @@
-[run]
-source = aiida_fleur
-omit = *test*
-
-[html]
-directory = coverage/html
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/JUDFT_WARN_ONLY b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/JUDFT_WARN_ONLY
new file mode 100644
index 000000000..65c71eb10
--- /dev/null
+++ b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/JUDFT_WARN_ONLY
@@ -0,0 +1 @@
+/n
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/_scheduler-stderr.txt b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/_scheduler-stderr.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/_scheduler-stdout.txt b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/_scheduler-stdout.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/inp.xml b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/inp.xml
new file mode 100644
index 000000000..4d34c362a
--- /dev/null
+++ b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/inp.xml
@@ -0,0 +1,368 @@
+
+
+
+ Si, alpha silicon, bulk, delta project
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.437500 0.437500 0.437500
+ 0.312500 0.437500 0.437500
+ 0.187500 0.437500 0.437500
+ 0.062500 0.437500 0.437500
+ 0.062500 0.500000 0.500000
+ 0.187500 0.562500 0.562500
+ 0.312500 0.562500 0.562500
+ 0.437500 0.437500 0.562500
+ 0.312500 0.312500 0.437500
+ 0.187500 0.312500 0.437500
+ 0.125000 0.375000 0.437500
+ 0.125000 0.437500 0.500000
+ 0.187500 0.500000 0.625000
+ 0.312500 0.437500 0.687500
+ 0.312500 0.437500 0.562500
+ 0.250000 0.250000 0.437500
+ 0.250000 0.375000 0.437500
+ 0.250000 0.437500 0.500000
+ 0.250000 0.437500 0.625000
+ 0.250000 0.500000 0.687500
+ 0.187500 0.437500 0.562500
+ 0.375000 0.375000 0.437500
+ 0.375000 0.437500 0.500000
+ 0.375000 0.437500 0.625000
+ 0.250000 0.562500 0.625000
+ 0.125000 0.500000 0.562500
+ 0.437500 0.500000 0.500000
+ 0.375000 0.500000 0.562500
+ 0.250000 0.500000 0.562500
+ 0.375000 0.375000 0.562500
+ 0.250000 0.375000 0.562500
+ 0.312500 0.312500 0.562500
+ 0.312500 0.312500 0.312500
+ 0.187500 0.312500 0.312500
+ 0.062500 0.312500 0.312500
+ 0.062500 0.375000 0.375000
+ 0.187500 0.500000 0.500000
+ 0.375000 0.375000 0.687500
+ 0.187500 0.187500 0.312500
+ 0.125000 0.250000 0.312500
+ 0.125000 0.312500 0.375000
+ 0.187500 0.375000 0.500000
+ 0.312500 0.500000 0.625000
+ 0.250000 0.250000 0.312500
+ 0.250000 0.312500 0.375000
+ 0.250000 0.312500 0.500000
+ 0.312500 0.375000 0.625000
+ 0.312500 0.375000 0.375000
+ 0.312500 0.375000 0.500000
+ 0.312500 0.500000 0.500000
+ 0.187500 0.187500 0.187500
+ 0.062500 0.187500 0.187500
+ 0.062500 0.250000 0.250000
+ 0.187500 0.375000 0.375000
+ 0.125000 0.125000 0.187500
+ 0.125000 0.187500 0.250000
+ 0.187500 0.250000 0.375000
+ 0.187500 0.250000 0.250000
+ 0.062500 0.062500 0.062500
+ 0.062500 0.125000 0.125000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+
+
+ .000000000000000 5.167355275200000 5.167355275200000
+ 5.167355275200000 .000000000000000 5.167355275200000
+ 5.167355275200000 5.167355275200000 .000000000000000
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ 1.000/8.000 1.000/8.000 1.000/8.000
+ -1.000/8.000 -1.000/8.000 -1.000/8.000
+
+
+
+
+
+
+
+
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/out.error b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/out.error
new file mode 100644
index 000000000..16cc26986
--- /dev/null
+++ b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/out.error
@@ -0,0 +1 @@
+_aiidasubmit.sh: line 7: ./local_exe/fleur: No such file or directory
diff --git a/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/shell.out b/tests/calculation/data_dir/mock-fleur-88edcca7024f2f2c75ac80044aa80644/shell.out
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/calculation/test_inpgen.py b/tests/calculation/test_inpgen.py
index 8946ba7aa..e7a27fc40 100644
--- a/tests/calculation/test_inpgen.py
+++ b/tests/calculation/test_inpgen.py
@@ -54,9 +54,9 @@ def test_fleurinpgen_default_calcinfo(aiida_profile, fixture_sandbox, generate_c
input_written = handle.read()
aiida_in_text = """A Fleur input generator calculation with aiida\n&input cartesian=F /
- 0.000000000 5.130606447 5.130606447
- 5.130606447 0.000000000 5.130606447
- 5.130606447 5.130606447 0.000000000
+ 0.000000000 5.130606429 5.130606429
+ 5.130606429 0.000000000 5.130606429
+ 5.130606429 5.130606429 0.000000000
1.0000000000
1.000000000 1.000000000 1.000000000
@@ -117,9 +117,9 @@ def test_fleurinpgen_with_parameters(aiida_profile, fixture_sandbox, generate_ca
input_written = handle.read()
aiida_in_text = """A Fleur input generator calculation with aiida\n&input cartesian=F /
- 0.000000000 5.130606447 5.130606447
- 5.130606447 0.000000000 5.130606447
- 5.130606447 5.130606447 0.000000000
+ 0.000000000 5.130606429 5.130606429
+ 5.130606429 0.000000000 5.130606429
+ 5.130606429 5.130606429 0.000000000
1.0000000000
1.000000000 1.000000000 1.000000000
diff --git a/tests/cmdline/__init__.py b/tests/cmdline/__init__.py
index 713971d59..e69de29bb 100644
--- a/tests/cmdline/__init__.py
+++ b/tests/cmdline/__init__.py
@@ -1,10 +0,0 @@
-# -*- coding: utf-8 -*-
-'''
-AiiDA-FLEUR
-'''
-
-__copyright__ = u'Copyright (c), 2015-2017, Forschungszentrum Juelich GmbH, Germany. All rights reserved.'
-__license__ = 'MIT license, see LICENSE.txt file.'
-__contributors__ = 'Jens Broeder'
-__paper__ = ''
-__paper_short__ = ''
diff --git a/tests/cmdline/conftest.py b/tests/cmdline/conftest.py
new file mode 100644
index 000000000..dbf830f8a
--- /dev/null
+++ b/tests/cmdline/conftest.py
@@ -0,0 +1,108 @@
+# -*- coding: utf-8 -*-
+# pylint: disable=redefined-outer-name
+"""Fixtures for the command line interface.
+Most of these fixtures are taken from the aiida-quantum espresso package since they
+are needed to mock commands running aiida process
+"""
+import pytest
+
+
+def mock_launch_process(*_, **__):
+ """Mock the :meth:`~aiida_fleur.cmdline.util.utils.launch_process` to be a no-op."""
+ return
+
+
+@pytest.fixture
+def import_with_migrate(temp_dir):
+ """Import an aiida export file and migrate it
+
+ We want to be able to run the test with several aiida versions,
+ therefore imports have to be migrate, but we also do not want to use verdi
+ """
+ # This function has some deep aiida imports which might change in the future
+ _DEFAULT_IMPORT_KWARGS = {'group': None}
+
+ def _import_with_migrate(filename, tempdir=temp_dir, import_kwargs=None, try_migration=True):
+ from click import echo
+ from aiida.tools.importexport import import_data
+ from aiida.tools.importexport import EXPORT_VERSION, IncompatibleArchiveVersionError
+ # these are only availbale after aiida >= 1.5.0, maybe rely on verdi import instead
+ from aiida.tools.importexport import detect_archive_type
+ from aiida.tools.importexport.archive.migrators import get_migrator
+ from aiida.tools.importexport.common.config import ExportFileFormat
+ if import_kwargs is None:
+ import_kwargs = _DEFAULT_IMPORT_KWARGS
+ archive_path = filename
+
+ try:
+ import_data(archive_path, **import_kwargs)
+ except IncompatibleArchiveVersionError as exception:
+ #raise ValueError
+ if try_migration:
+ echo(f'incompatible version detected for {archive_path}, trying migration')
+ migrator = get_migrator(detect_archive_type(archive_path))(archive_path)
+ archive_path = migrator.migrate(EXPORT_VERSION, None, out_compression='none', work_dir=tempdir)
+ import_data(archive_path, **import_kwargs)
+
+ return _import_with_migrate
+
+
+@pytest.fixture
+def struct_file_type():
+ """Return instance of ``StructureNodeOrFileParamType``."""
+ from aiida_fleur.cmdline.util.types import StructureNodeOrFileParamType
+ return StructureNodeOrFileParamType()
+
+
+@pytest.fixture
+def run_cli_command():
+ """Run a `click` command with the given options.
+
+ The call will raise if the command triggered an exception or the exit code returned is non-zero.
+ """
+
+ def _run_cli_command(command, options=None, raises=None):
+ """Run the command and check the result.
+
+ :param command: the command to invoke
+ :param options: the list of command line options to pass to the command invocation
+ :param raises: optionally an exception class that is expected to be raised
+ """
+ import traceback
+ from click.testing import CliRunner
+
+ runner = CliRunner()
+ result = runner.invoke(command, options or [])
+
+ if raises is not None:
+ assert result.exception is not None, result.output
+ assert result.exit_code != 0
+ else:
+ assert result.exception is None, ''.join(traceback.format_exception(*result.exc_info))
+ assert result.exit_code == 0, result.output
+
+ result.output_lines = [line.strip() for line in result.output.split('\n') if line.strip()]
+
+ return result
+
+ return _run_cli_command
+
+
+@pytest.fixture
+def run_cli_process_launch_command(run_cli_command, monkeypatch):
+ """Run a process launch command with the given options.
+
+ The call will raise if the command triggered an exception or the exit code returned is non-zero.
+
+ :param command: the command to invoke
+ :param options: the list of command line options to pass to the command invocation
+ :param raises: optionally an exception class that is expected to be raised
+ """
+
+ def _inner(command, options=None, raises=None):
+ """Run the command and check the result."""
+ from aiida_fleur.cmdline.util import utils
+ monkeypatch.setattr(utils, 'launch_process', mock_launch_process)
+ return run_cli_command(command, options, raises)
+
+ return _inner
diff --git a/tests/cmdline/data/__init__.py b/tests/cmdline/data/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmdline/data/test_fleurinp.py b/tests/cmdline/data/test_fleurinp.py
new file mode 100644
index 000000000..cefa74d9a
--- /dev/null
+++ b/tests/cmdline/data/test_fleurinp.py
@@ -0,0 +1,52 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI data fleurinp commands.
+'''
+import os
+from aiida.orm import Dict
+file_path1 = '../../files/inpxml/FePt/inp.xml'
+file_path2 = '../../files/inpxml/Si/inp.xml'
+
+inpxmlfilefolder = os.path.dirname(os.path.abspath(__file__))
+FEPT_INPXML_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path1))
+SI_INPXML_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path2))
+
+
+def test_cmd_fleurinp_list(run_cli_command, create_fleurinp):
+ """Test invoking the data fleurinp list command."""
+ from aiida_fleur.cmdline.data.fleurinp import list_fleurinp
+
+ fleurinp = create_fleurinp(FEPT_INPXML_FILE)
+ fleurinp.store()
+ options = ['--uuid', '--ctime', '--strucinfo']
+ results = run_cli_command(list_fleurinp, options=options)
+ print(results.output_lines)
+ assert fleurinp.uuid in results.output
+
+ fleurinp2 = create_fleurinp(SI_INPXML_FILE)
+ fleurinp2.store()
+ options = ['--uuid', '--ctime', '--strucinfo', '--raw']
+ results = run_cli_command(list_fleurinp, options=options)
+ assert fleurinp.uuid in results.output
+ assert fleurinp2.uuid in results.output
+
+
+def test_cmd_fleurinp_cat(run_cli_command, create_fleurinp):
+ """Test invoking the data fleurinp cat command."""
+ from aiida_fleur.cmdline.data.fleurinp import cat_file
+
+ fleurinp = create_fleurinp(FEPT_INPXML_FILE)
+ fleurinp.store()
+ options = [fleurinp.uuid]
+ result = run_cli_command(cat_file, options=options)
+ # printed contents will also put in line breaks \n which makes comparisson hard.
diff --git a/tests/cmdline/data/test_parameters.py b/tests/cmdline/data/test_parameters.py
new file mode 100644
index 000000000..aac6ae6b7
--- /dev/null
+++ b/tests/cmdline/data/test_parameters.py
@@ -0,0 +1,42 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI data parameter commands.
+'''
+import os
+from aiida.orm import Dict
+file_path1 = '../../files/inpxml/Si/inp.xml'
+
+inpxmlfilefolder = os.path.dirname(os.path.abspath(__file__))
+SI_INPXML_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path1))
+
+
+def test_cmd_param_import(run_cli_command):
+ """Test invoking the import parameter command in all variants."""
+ from shutil import copyfile
+ from aiida_fleur.cmdline.data.parameters import cmd_param_import
+
+ options = [SI_INPXML_FILE, '--fleurinp']
+ run_cli_command(cmd_param_import, options=options)
+
+ options = [SI_INPXML_FILE, '--fleurinp', '--dry-run']
+ run_cli_command(cmd_param_import, options=options)
+
+ options = [SI_INPXML_FILE, '--show', '--dry-run']
+ run_cli_command(cmd_param_import, options=options)
+
+ dest_path = SI_INPXML_FILE.strip('.xml')
+ copyfile(SI_INPXML_FILE, dest_path)
+ options = [dest_path, '--fleurinp', '--dry-run']
+ result = run_cli_command(cmd_param_import, options=options, raises=True)
+ os.remove(dest_path)
+ assert 'Critical: Error: Currently, we can only extract information from an inp.xml file.' in result.output_lines
diff --git a/tests/cmdline/data/test_structure.py b/tests/cmdline/data/test_structure.py
new file mode 100644
index 000000000..251998077
--- /dev/null
+++ b/tests/cmdline/data/test_structure.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI data structure commands.
+'''
+import os
+from aiida.orm import Dict
+file_path1 = '../../files/inpxml/FePt/inp.xml'
+
+inpxmlfilefolder = os.path.dirname(os.path.abspath(__file__))
+FEPT_INPXML_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path1))
+
+
+def test_import_structure(run_cli_command):
+ """Test invoking the import structure command in all variants."""
+ from shutil import copyfile
+ from aiida_fleur.cmdline.data.structure import cmd_import
+
+ options = [FEPT_INPXML_FILE, '--fleurinp']
+ run_cli_command(cmd_import, options=options)
+
+ options = [FEPT_INPXML_FILE, '--fleurinp', '--dry-run']
+ run_cli_command(cmd_import, options=options)
+
+ dest_path = FEPT_INPXML_FILE.strip('.xml')
+ copyfile(FEPT_INPXML_FILE, dest_path)
+ options = [dest_path, '--fleurinp', '--dry-run']
+ result = run_cli_command(cmd_import, options=options, raises=True)
+ os.remove(dest_path)
+ assert 'Critical: Error: Currently, only StructureData from a inp.xml file can be '\
+ 'extracted.' in result.output_lines
diff --git a/tests/cmdline/launch/__init__.py b/tests/cmdline/launch/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmdline/launch/test_launch.py b/tests/cmdline/launch/test_launch.py
new file mode 100644
index 000000000..583d70f55
--- /dev/null
+++ b/tests/cmdline/launch/test_launch.py
@@ -0,0 +1,237 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI commands to launch for calcjob and workflows of aiida-fleur.
+
+Comment: while 'launch process' is mocked to do nothing these tests are still quite slow
+but execute large parts of the workchain code base.
+'''
+import os
+from aiida.orm import Dict
+file_path1 = '../../files/inpxml/FePt/inp.xml'
+
+inpxmlfilefolder = os.path.dirname(os.path.abspath(__file__))
+FEPT_INPXML_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path1))
+
+
+def test_launch_inpgen_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the inpgen launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_inpgen
+
+ code = fixture_code('fleur.inpgen').store()
+ options = ['--inpgen', code.uuid]
+ run_cli_process_launch_command(launch_inpgen, options=options)
+
+ options = ['--inpgen', code.uuid, '--daemon']
+ run_cli_process_launch_command(launch_inpgen, options=options)
+
+
+def test_launch_fleur_base(run_cli_process_launch_command, fixture_code, create_fleurinp):
+ """Test invoking the fleur launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_fleur
+
+ code = fixture_code('fleur.fleur').store()
+ fleurinp = create_fleurinp(FEPT_INPXML_FILE).store()
+
+ #Calcjob
+ options = ['--fleur', code.uuid, '-inp', fleurinp.uuid, '--no-launch_base']
+ run_cli_process_launch_command(launch_fleur, options=options)
+
+ #Base_fleur
+ options = ['--fleur', code.uuid, '-inp', fleurinp.uuid]
+ run_cli_process_launch_command(launch_fleur, options=options)
+
+
+def test_launch_scf_base(run_cli_process_launch_command, fixture_code, create_fleurinp):
+ """Test invoking the scf workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_scf
+
+ #Path 1
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid]
+ run_cli_process_launch_command(launch_scf, options=options)
+
+ #Path2
+ fleurinp = create_fleurinp(FEPT_INPXML_FILE).store()
+ options = ['--fleur', fleur.uuid, '-inp', fleurinp.uuid]
+ run_cli_process_launch_command(launch_scf, options=options)
+
+
+def test_launch_eos_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the eos workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_eos
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid]
+ run_cli_process_launch_command(launch_eos, options=options)
+
+
+def test_launch_relax_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the relax workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_relax
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid]
+ run_cli_process_launch_command(launch_relax, options=options)
+
+
+def test_launch_corehole_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the corehole workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_corehole
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid]
+ run_cli_process_launch_command(launch_corehole, options=options)
+
+
+def test_launch_init_cls_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the initial_cls workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_init_cls
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid]
+ run_cli_process_launch_command(launch_init_cls, options=options)
+
+
+def test_launch_banddos_base(run_cli_process_launch_command, fixture_code, generate_remote_data, create_fleurinp):
+ """Test invoking the banddow workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_banddos
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+ path = os.path.abspath(os.path.join(inpxmlfilefolder, '../../files/outxml/tmp'))
+ remote = generate_remote_data(fleur.computer, path).store()
+ fleurinp = create_fleurinp(FEPT_INPXML_FILE).store()
+
+ options = ['--fleur', fleur.uuid, '-P', remote.uuid, '-inp', fleurinp.uuid]
+ run_cli_process_launch_command(launch_banddos, options=options)
+
+
+def test_launch_mae_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the mae workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_mae
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+
+ wf_para = {
+ 'lattice': 'fcc',
+ 'miller': [[-1, 1, 0], [0, 0, 1], [1, 1, 0]],
+ 'host_symbol': 'Pt',
+ 'latticeconstant': 4.0,
+ 'size': (1, 1, 5),
+ 'replacements': {
+ 0: 'Fe',
+ -1: 'Fe'
+ },
+ 'decimals': 10,
+ 'pop_last_layers': 1,
+ 'total_number_layers': 8,
+ 'num_relaxed_layers': 3
+ }
+
+ wf_para = Dict(dict=wf_para).store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid, '-wf', wf_para.uuid]
+ run_cli_process_launch_command(launch_mae, options=options)
+
+
+def test_launch_create_magnetic_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the mae workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_create_magnetic
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+
+ wf_para = {
+ 'sqa_ref': [0.7, 0.7],
+ 'use_soc_ref': False,
+ 'sqas_theta': [0.0, 1.57079, 1.57079],
+ 'sqas_phi': [0.0, 0.0, 1.57079],
+ 'serial': False,
+ 'soc_off': [],
+ 'inpxml_changes': [],
+ }
+
+ wf_para = Dict(dict=wf_para).store()
+
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid, '-wf', wf_para.uuid]
+ run_cli_process_launch_command(launch_create_magnetic, options=options)
+
+
+def test_launch_dmi_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the mae workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_dmi
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+
+ wf_para = {
+ 'serial': False,
+ 'beta': {
+ '123': 1.57079
+ },
+ 'sqas_theta': [0.0, 1.57079, 1.57079],
+ 'sqas_phi': [0.0, 0.0, 1.57079],
+ 'soc_off': [],
+ # 'prop_dir': [0.125, 0.15, 0.24],
+ 'q_vectors': [[0.0, 0.0, 0.0], [0.1, 0.1, 0.0]],
+ 'ref_qss': [0.0, 0.0, 0.0],
+ 'inpxml_changes': []
+ }
+
+ wf_para = Dict(dict=wf_para).store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid, '-wf', wf_para.uuid]
+ run_cli_process_launch_command(launch_dmi, options=options)
+
+
+def test_launch_ssdisp_base(run_cli_process_launch_command, fixture_code):
+ """Test invoking the mae workchain launch command with only required inputs."""
+ from aiida_fleur.cmdline.launch import launch_ssdisp
+
+ inpgen = fixture_code('fleur.inpgen').store()
+ fleur = fixture_code('fleur.fleur').store()
+
+ wf_para = {
+ 'lattice': 'fcc',
+ 'miller': [[-1, 1, 0], [0, 0, 1], [1, 1, 0]],
+ 'host_symbol': 'Pt',
+ 'latticeconstant': 4.0,
+ 'size': (1, 1, 5),
+ 'replacements': {
+ 0: 'Fe',
+ -1: 'Fe'
+ },
+ 'decimals': 10,
+ 'pop_last_layers': 1,
+ 'total_number_layers': 8,
+ 'num_relaxed_layers': 3
+ }
+
+ wf_para = {
+ 'beta': {
+ 'all': 1.57079
+ },
+ 'prop_dir': [0.125, 0.125, 0.0],
+ 'q_vectors': [[0.0, 0.0, 0.0], [0.125, 0.125, 0.0], [0.250, 0.250, 0.0], [0.375, 0.375, 0.0],
+ [0.500, 0.500, 0.0]],
+ 'ref_qss': [0.0, 0.0, 0.0],
+ 'inpxml_changes': []
+ }
+
+ wf_para = Dict(dict=wf_para).store()
+ options = ['--inpgen', inpgen.uuid, '--fleur', fleur.uuid, '-wf', wf_para.uuid]
+ run_cli_process_launch_command(launch_ssdisp, options=options)
diff --git a/tests/cmdline/test_base_all_commands.py b/tests/cmdline/test_base_all_commands.py
new file mode 100644
index 000000000..a3911bf0f
--- /dev/null
+++ b/tests/cmdline/test_base_all_commands.py
@@ -0,0 +1,23 @@
+# -*- coding: utf-8 -*-
+"""Tests if all available CLI commands can print help."""
+from click import Context, Group
+from aiida_fleur.cmdline import cmd_root
+
+
+def test_base_all_commands():
+ """Test that all commands in ``cmd_root`` are reachable and can print the help message.
+
+ This doesn't guarantee that the command works but at least that it can be successfully called and there are no
+ import errors or other basic problems.
+ """
+
+ def recursively_print_help(ctx):
+ assert isinstance(ctx.get_help(), str)
+
+ if isinstance(ctx.command, Group):
+ for subcommand in ctx.command.commands.values():
+ ctx.command = subcommand
+ recursively_print_help(ctx)
+
+ ctx = Context(cmd_root)
+ recursively_print_help(ctx)
diff --git a/tests/cmdline/test_types.py b/tests/cmdline/test_types.py
new file mode 100644
index 000000000..407766326
--- /dev/null
+++ b/tests/cmdline/test_types.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI types of the package.
+'''
+import pytest
+import os
+import click
+from aiida.orm import StructureData
+
+file_path1 = '../files/cif/AlB.cif'
+
+inpxmlfilefolder = os.path.dirname(os.path.abspath(__file__))
+CIF_FILE = os.path.abspath(os.path.join(inpxmlfilefolder, file_path1))
+
+
+class TestStructureNodeOrFileParamType:
+ """Test the ``StructureNodeOrFileParamType``"""
+
+ def test_not_existent_structure(self, struct_file_type):
+ """Test failure if identifier given but NotExistent"""
+ with pytest.raises(click.BadParameter):
+ struct_file_type.convert('7000', None, None)
+
+ def test_path_give(self, struct_file_type):
+ """Test if it can take a cif file"""
+ result = struct_file_type.convert(CIF_FILE, None, None)
+ assert isinstance(result, StructureData)
+
+ def test_parse_duplicate(self, struct_file_type):
+ """Test if duplicates are not stored again"""
+ result = struct_file_type.convert(CIF_FILE, None, None)
+ structure = result.store()
+
+ result = struct_file_type.convert(CIF_FILE, None, None)
+ assert result.uuid == structure.uuid
diff --git a/tests/cmdline/visualization/__init__.py b/tests/cmdline/visualization/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmdline/visualization/test_plot.py b/tests/cmdline/visualization/test_plot.py
new file mode 100644
index 000000000..36477dd8f
--- /dev/null
+++ b/tests/cmdline/visualization/test_plot.py
@@ -0,0 +1,48 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test the plot cmd from the commandline
+'''
+
+import os
+import pytest
+import aiida
+from packaging import version
+
+file_path = '../../files/exports/fleur_scf_fleurinp_Si.tar.gz'
+thisfilefolder = os.path.dirname(os.path.abspath(__file__))
+EXPORTFILE_FILE = os.path.abspath(os.path.join(thisfilefolder, file_path))
+
+
+@pytest.mark.skipif(version.parse(aiida.__version__) < version.parse('1.5.0'),
+ reason='archive import and migration works only with aiida-core > 1.5.0')
+def test_cmd_plot(run_cli_command, temp_dir, import_with_migrate):
+ """Test invoking the plot command in all variants.
+
+ If this test hangs, --no-show is not working
+ """
+ from aiida_fleur.cmdline.visualization import cmd_plot
+
+ # import an an aiida export, this does not migrate
+ import_with_migrate(EXPORTFILE_FILE)
+ process_uuid = '7f9f4cfb-4170-48ea-801d-4269f88792e0'
+
+ options = [process_uuid, '--no-show']
+ result = run_cli_command(cmd_plot, options=options)
+
+ # provide a file with ids
+ tempfile_name = os.path.join(temp_dir, 'test_uuids.txt')
+ with open(tempfile_name, 'w') as file1:
+ file1.write('7f9f4cfb-4170-48ea-801d-4269f88792e0\n7f9f4cfb-4170-48ea-801d-4269f88792e0')
+ options = [process_uuid, '--no-show', '-f', tempfile_name]
+ result = run_cli_command(cmd_plot, options=options)
+ os.remove(tempfile_name)
diff --git a/tests/cmdline/workflows/__init__.py b/tests/cmdline/workflows/__init__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/cmdline/workflows/test_worklow_cmd.py b/tests/cmdline/workflows/test_worklow_cmd.py
new file mode 100644
index 000000000..f8909b7aa
--- /dev/null
+++ b/tests/cmdline/workflows/test_worklow_cmd.py
@@ -0,0 +1,80 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all CLI workflow commands.
+'''
+
+import os
+import pytest
+import aiida
+from packaging import version
+
+file_path = '../../files/exports/fleur_scf_fleurinp_Si.tar.gz'
+thisfilefolder = os.path.dirname(os.path.abspath(__file__))
+EXPORTFILE_FILE = os.path.abspath(os.path.join(thisfilefolder, file_path))
+
+
+@pytest.mark.skipif(version.parse(aiida.__version__) < version.parse('1.5.0'),
+ reason='archive import and migration works only with aiida-core > 1.5.0')
+def test_workchain_res(run_cli_command, import_with_migrate):
+ """Test invoking the workchain res command in all variants."""
+ from aiida_fleur.cmdline.workflows import workchain_res
+
+ EXPECTED1 = '"total_energy": -580.0719889044,'
+ EXPECTED2 = '"energy_core_electrons": -316.8117066016,'
+ # import an an aiida export, this does not migrate
+ #import_data(EXPORTFILE_FILE, group=None)
+ import_with_migrate(EXPORTFILE_FILE)
+ process_uuid = '7f9f4cfb-4170-48ea-801d-4269f88792e0'
+
+ options = [process_uuid]
+ result = run_cli_command(workchain_res, options=options)
+ assert EXPECTED1 in result.output_lines
+ assert EXPECTED2 in result.output_lines
+
+ # only one node
+ options = [process_uuid, '-l', 'output_scf_wc_para', '--info', '--keys', 'total_energy', 'total_wall_time']
+ result = run_cli_command(workchain_res, options=options)
+ assert EXPECTED1 in result.output_lines
+ assert EXPECTED2 not in result.output_lines
+ assert 'Info:' in result.output_lines[0]
+
+ options = [process_uuid, '--keys', 'nothere']
+ run_cli_command(workchain_res, options=options, raises=KeyError)
+
+
+@pytest.mark.skipif(version.parse(aiida.__version__) < version.parse('1.5.0'),
+ reason='archive import and migration works only with aiida-core > 1.5.0')
+def test_workchain_inputdict(run_cli_command, import_with_migrate):
+ """Test invoking the workchain inputdict command in all variants."""
+ from aiida_fleur.cmdline.workflows import workchain_inputdict
+
+ # import an an aiida export, this does not migrate
+ #import_data(EXPORTFILE_FILE, group=None)
+ import_with_migrate(EXPORTFILE_FILE)
+ EXPECTED = '"max_wallclock_seconds": 300,'
+ EXPECTED2 = '"num_machines": 1,'
+ process_uuid = '7f9f4cfb-4170-48ea-801d-4269f88792e0'
+
+ options = [process_uuid]
+ result = run_cli_command(workchain_inputdict, options=options)
+ assert EXPECTED in result.output_lines
+ assert EXPECTED2 in result.output_lines
+
+ options = [process_uuid, '--info', '-l', 'options', '--keys', 'max_wallclock_seconds', 'withmpi']
+ result = run_cli_command(workchain_inputdict, options=options)
+ assert EXPECTED in result.output_lines
+ assert EXPECTED2 not in result.output_lines
+ assert 'Info:' in result.output_lines[0]
+
+ options = [process_uuid, '--keys', 'nothere']
+ run_cli_command(workchain_inputdict, options=options, raises=KeyError)
diff --git a/tests/common/__initi__.py b/tests/common/__initi__.py
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/common/test_node_generators.py b/tests/common/test_node_generators.py
new file mode 100644
index 000000000..cd09fd2cd
--- /dev/null
+++ b/tests/common/test_node_generators.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''
+Module to test all common node_generators
+
+
+import pytest
+from aiida_fleur.common.node_generators import generate_option_dict, generate_option_node
+from aiida_fleur.common.node_generators import generate_wf_para_dict, generate_wf_para_node
+
+ALL_ENTRYPOINTS_CALCS = ['fleur.fleur', 'fleur.inpgen']
+ALL_ENTRYPOINTS_WC = ['fleur.base', 'fleur.scf', 'fleur.relax', 'fleur.base_relax', 'fleur.eos',
+ 'fleur.corehole', 'fleur.init_cls', 'fleur.banddos', 'fleur.mae', 'fleur.dmi', 'fleur.ssdisp',
+ 'fleur.create_magnetic']
+
+def test_generate_option_dict_defaults_wc(entrypoint):
+ """Tests if the generate_option_dict function can get all the default options from the workchains
+
+ i.e this also tests if all fleur workchains have defined some _default_option
+ """
+ default_dict = generate_option_dict(wf_entry_point=entrypoint)
+ assert isinstance(default_dict, dict)
+
+def test_generate_option_node_interface():
+ """
+
+ """
+ pass
+
+@pytest.mark.parametrize('entrypoint', ALL_ENTRYPOINTS_WC)
+def test_generate_wf_para_dict_defaults_wc(entrypoint):
+ """Tests if the generate_option_dict function can get all the default options from the workchains
+
+ i.e this also tests if all fleur workchains have defined some _default_option
+ """
+ default_dict = generate_wf_para_dict(wf_entry_point=entrypoint)
+ assert isinstance(default_dict, dict)
+'''
diff --git a/tests/conftest.py b/tests/conftest.py
index 08c6c6bfa..74ec02f82 100644
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -8,7 +8,6 @@
import os
import collections
import pytest
-import six
import sys
from aiida.orm import Node, Code, Dict, RemoteData, CalcJobNode
@@ -50,6 +49,7 @@ def fixture_code(fixture_localhost):
"""Return a `Code` instance configured to run calculations of given entry point on localhost `Computer`."""
def _fixture_code(entry_point_name):
+
return Code(input_plugin_name=entry_point_name, remote_computer_exec=[fixture_localhost, '/bin/ls'])
return _fixture_code
@@ -83,20 +83,26 @@ def _generate_calc_job(folder, entry_point_name, inputs=None):
@pytest.fixture
-def generate_calc_job_node():
+def generate_calc_job_node(fixture_localhost):
"""Fixture to generate a mock `CalcJobNode` for testing parsers."""
def flatten_inputs(inputs, prefix=''):
"""Flatten inputs recursively like :meth:`aiida.engine.processes.process::Process._flatten_inputs`."""
flat_inputs = []
- for key, value in six.iteritems(inputs):
+ for key, value in inputs.items():
if isinstance(value, collections.Mapping):
flat_inputs.extend(flatten_inputs(value, prefix=prefix + key + '__'))
else:
flat_inputs.append((prefix + key, value))
return flat_inputs
- def _generate_calc_job_node(entry_point_name, computer, test_name=None, inputs=None, attributes=None):
+ def _generate_calc_job_node(entry_point_name,
+ computer=None,
+ test_name=None,
+ inputs=None,
+ attributes=None,
+ store=False,
+ retrieve_list=None):
"""Fixture to generate a mock `CalcJobNode` for testing parsers.
:param entry_point_name: entry point name of the calculation class
@@ -110,6 +116,9 @@ def _generate_calc_job_node(entry_point_name, computer, test_name=None, inputs=N
from aiida.common import LinkType
from aiida.plugins.entry_point import format_entry_point_string
+ if computer is None:
+ computer = fixture_localhost
+
entry_point = format_entry_point_string('aiida.calculations', entry_point_name)
node = orm.CalcJobNode(computer=computer, process_type=entry_point)
@@ -120,6 +129,8 @@ def _generate_calc_job_node(entry_point_name, computer, test_name=None, inputs=N
node.set_option('withmpi', True)
node.set_option('max_wallclock_seconds', 1800)
+ if retrieve_list is not None:
+ node.set_attribute('retrieve_list', retrieve_list)
if attributes:
node.set_attribute_many(attributes)
@@ -128,12 +139,12 @@ def _generate_calc_job_node(entry_point_name, computer, test_name=None, inputs=N
input_node.store()
node.add_incoming(input_node, link_type=LinkType.INPUT_CALC, link_label=link_label)
- # node.store()
+ if store: # needed if test_name is not None
+ node.store()
if test_name is not None:
basepath = os.path.dirname(os.path.abspath(__file__))
- filepath = os.path.join(basepath, 'parsers', 'fixtures', entry_point_name[len('quantumespresso.'):],
- test_name)
+ filepath = os.path.join(basepath, 'parsers', 'fixtures', entry_point_name[len('fleur.'):], test_name)
retrieved = orm.FolderData()
retrieved.put_object_from_tree(filepath)
@@ -205,7 +216,7 @@ def generate_remote_data():
"""Return a `RemoteData` node."""
def _generate_remote_data(computer, remote_path, entry_point_name=None):
- """Return a `KpointsData` with a mesh of npoints in each direction."""
+ """Return a `RemoteData` node pointing to given path."""
from aiida.common.links import LinkType
from aiida.plugins.entry_point import format_entry_point_string
@@ -261,7 +272,7 @@ def generate_work_chain_node():
def flatten_inputs(inputs, prefix=''):
"""Flatten inputs recursively like :meth:`aiida.engine.processes.process::Process._flatten_inputs`."""
flat_inputs = []
- for key, value in six.iteritems(inputs):
+ for key, value in inputs.items():
if isinstance(value, collections.Mapping):
flat_inputs.extend(flatten_inputs(value, prefix=prefix + key + '__'))
else:
@@ -320,14 +331,13 @@ def generate_film_structure():
def _generate_film_structure():
"""Return a `StructureData` representing bulk silicon."""
from aiida.orm import StructureData
-
- bohr_a_0 = 0.52917721092 # A
- a = 7.497 * bohr_a_0
+ from aiida_fleur.common.constants import BOHR_A
+ a = 7.497 * BOHR_A
cell = [[0.7071068 * a, 0.0, 0.0], [0.0, 1.0 * a, 0.0], [0.0, 0.0, 0.7071068 * a]]
structure = StructureData(cell=cell)
- structure.append_atom(position=(0., 0., -1.99285 * bohr_a_0), symbols='Fe')
+ structure.append_atom(position=(0., 0., -1.99285 * BOHR_A), symbols='Fe')
structure.append_atom(position=(0.5 * 0.7071068 * a, 0.5 * a, 0.0), symbols='Pt')
- structure.append_atom(position=(0., 0., 2.65059 * bohr_a_0), symbols='Pt')
+ structure.append_atom(position=(0., 0., 2.65059 * BOHR_A), symbols='Pt')
structure.pbc = (True, True, False)
return structure
diff --git a/tests/coverage.svg b/tests/coverage.svg
deleted file mode 100644
index f86374a02..000000000
--- a/tests/coverage.svg
+++ /dev/null
@@ -1,21 +0,0 @@
-
-
diff --git a/tests/data/test_fleurinp.py b/tests/data/test_fleurinp.py
index d7b6b9f1b..0f6ec26bb 100644
--- a/tests/data/test_fleurinp.py
+++ b/tests/data/test_fleurinp.py
@@ -117,10 +117,10 @@ def test_fleurinp_structuredata_extraction(create_fleurinp, inpxmlfilepath):
assert isinstance(struc, StructureData)
else:
pass
- # What todo here, may test inpxml are with latnam definded,
- # which does not work here.
- # But if something else fails also None return. T
- # Therefore this test might let two much through
+ # # What todo here, may test inpxml are with latnam definded,
+ # # which does not work here.
+ # # But if something else fails also None return. T
+ # # Therefore this test might let two much through
# Input Modification tests
@@ -145,8 +145,9 @@ def test_fleurinp_single_value_modification(create_fleurinp, inpxmlfilepath):
@pytest.mark.parametrize('inpxmlfilepath', inpxmlfilelist)
-def test_fleurinp_first_species_modification(create_fleurinp, inpxmlfilepath):
- """
- Decrease the rmt of the first species by 10%, check if rmt was set
- """
- return
+def test_get_tag(create_fleurinp, inpxmlfilepath):
+
+ fleurinp_tmp = create_fleurinp(inpxmlfilepath)
+ tag = fleurinp_tmp.get_tag('/fleurInput/atomSpecies/species')
+
+ assert tag != []
diff --git a/tests/data/test_fleurinpmodifier.py b/tests/data/test_fleurinpmodifier.py
index 07c294bab..270884d7b 100644
--- a/tests/data/test_fleurinpmodifier.py
+++ b/tests/data/test_fleurinpmodifier.py
@@ -14,6 +14,7 @@
from __future__ import absolute_import
import os
import pytest
+from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
# Collect the input files
file_path1 = '../files/inpxml/FePt/inp.xml'
@@ -23,7 +24,7 @@
def test_fleurinp_modifier1(create_fleurinp):
- from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
+ """Tests if fleurinp_modifier with various modifations on species"""
fleurinp_tmp = create_fleurinp(inpxmlfilefolder)
fm = FleurinpModifier(fleurinp_tmp)
@@ -43,15 +44,25 @@ def test_fleurinp_modifier1(create_fleurinp):
fm.show(validate=True)
fm.freeze()
+ fm = FleurinpModifier(fleurinp_tmp)
+ fm.set_inpchanges({'dos': True, 'Kmax': 3.9})
+ fm.undo(revert_all=True)
+ changes = fm.changes()
+ assert changes == []
+
def test_fleurinp_modifier2(create_fleurinp, inpxml_etree):
- from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
+ """Tests if fleurinp_modifier with various other modifations methods,
+ the detailed tests for method functionality is tested elsewhere."""
from aiida_fleur.tools.xml_util import eval_xpath
fleurinp_tmp = create_fleurinp(inpxmlfilefolder)
etree = inpxml_etree(inpxmlfilefolder)
fm = FleurinpModifier(fleurinp_tmp)
+ actions = fm.get_avail_actions()
+ assert isinstance(actions, dict)
+
new_tag = eval_xpath(etree, '/fleurInput/calculationSetup/scfLoop')
fm.delete_tag('/fleurInput/calculationSetup/scfLoop')
fm.replace_tag('/fleurInput/calculationSetup/cutoffs', new_tag)
@@ -66,6 +77,11 @@ def test_fleurinp_modifier2(create_fleurinp, inpxml_etree):
fm.set_species_label(' 222', {'mtSphere': {'radius': 3.333}})
fm.set_atomgr_att_label(attributedict={'force': [('relaxXYZ', 'FFF')]}, atom_label=' 222')
fm.set_atomgr_att(attributedict={'force': [('relaxXYZ', 'TFF')]}, species='Fe-1')
+
+ fm.set_nkpts(500, gamma='T')
+ fm.set_kpath({'gamma': (0, 0, 0), 'L': (0.1, 0.1, 0.1)}, 300)
+ fm.add_num_to_att('/fleurInput/calculationSetup/soc', 'theta', 4)
+ #fm.set_species1
fm.show()
@@ -76,12 +92,60 @@ def test_fleurinp_modifier2(create_fleurinp, inpxml_etree):
inpxmlfilefolder2 = os.path.abspath(os.path.join(inpxmlfilefolder2, file_path2))
-def test_fleurinp_modifier3(create_fleurinp):
- from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
+def test_fleurinp_modifier_set_nmmpmat(create_fleurinp):
+ """Tests if set_nmmpmat works on fleurinp modifier works, with right interface"""
fleurinp_tmp = create_fleurinp(inpxmlfilefolder2)
fm = FleurinpModifier(fleurinp_tmp)
fm.set_nmmpmat('Ga-1', orbital=2, spin=1, occStates=[1, 2, 3, 4, 5])
fm.set_nmmpmat('As-2', orbital=1, spin=1, denmat=[[1, -2, 3], [4, -5, 6], [7, -8, 9]])
+
+ # Does not validate
+ # Found invalid diagonal element for species Ga-1, spin 1 and l=2
+ with pytest.raises(ValueError):
+ fm.show(validate=True, display=False)
new_fleurinp = fm.freeze()
assert 'n_mmp_mat' in new_fleurinp.files
+
+
+def test_fleurinp_modifier_set_kpointsdata(create_fleurinp):
+ """Test if setting a kpoints list to a fleurinp data node works"""
+ from aiida.orm import KpointsData
+
+ fleurinp_tmp = create_fleurinp(inpxmlfilefolder)
+ fleurinp_tmp.store() # needed?
+ struc = fleurinp_tmp.get_structuredata_ncf()
+
+ kps = KpointsData()
+ kps.set_cell(struc.cell)
+ kps.pbc = struc.pbc
+ kpoints_pos = [[0.0, 0.0, 0.0], [0.0, 0.5, 0.0], [0.5, 0.0, 0.0], [0.5, 0.0, 0.5], [0.5, 0.5, 0.5], [1.0, 1.0, 1.0]]
+ kpoints_weight = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0]
+ # Fleur renormalizes
+ kps.set_kpoints(kpoints_pos, cartesian=False, weights=kpoints_weight)
+
+ kps.store() # needed, because node has to be loaded...
+ #print(fleurinp_tmp)
+ fm = FleurinpModifier(fleurinp_tmp)
+ fm.set_kpointsdata(kps)
+
+ fm.show(validate=True, display=False)
+ fm.freeze()
+
+ # check if kpoint node is input into modification
+ # uuid of node show also work
+ fm = FleurinpModifier(fleurinp_tmp)
+ fm.set_kpointsdata(kps.uuid)
+ fm.freeze()
+
+
+def test_fleurinpmodifier_error_messages(create_fleurinp):
+ """Test error interface of fleurinpmodifier"""
+ fleurinp_tmp = create_fleurinp(inpxmlfilefolder)
+
+ fm = FleurinpModifier(fleurinp_tmp)
+ fm._tasks.append(('not_existent', 1, 2, 3)) # task does not exists.
+ with pytest.raises(ValueError):
+ fm.freeze()
+
+ fm = FleurinpModifier(fleurinp_tmp)
diff --git a/tests/files/exports/base_export_regression_tests.tar.gz b/tests/files/exports/base_export_regression_tests.tar.gz
new file mode 100644
index 000000000..93e26be53
Binary files /dev/null and b/tests/files/exports/base_export_regression_tests.tar.gz differ
diff --git a/tests/files/exports/fleur_scf_fleurinp_Si.tar.gz b/tests/files/exports/fleur_scf_fleurinp_Si.tar.gz
new file mode 100644
index 000000000..a2dd39448
Binary files /dev/null and b/tests/files/exports/fleur_scf_fleurinp_Si.tar.gz differ
diff --git a/tests/files/outxml/all_test/Fe_relax_out.xml b/tests/files/outxml/all_test/Fe_relax_out.xml
new file mode 100644
index 000000000..14207dadb
--- /dev/null
+++ b/tests/files/outxml/all_test/Fe_relax_out.xml
@@ -0,0 +1,474 @@
+
+
+
+
+
+ GEN
+
+
+
+
+
+
+
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.416667 0.416667 0.416667
+ 0.416667 0.416667 0.250000
+ 0.416667 0.416667 0.083333
+ 0.416667 0.250000 0.250000
+ 0.416667 0.250000 0.083333
+ 0.416667 0.083333 0.083333
+ 0.250000 0.250000 0.250000
+ 0.250000 0.250000 0.083333
+ 0.250000 0.083333 0.083333
+ 0.083333 0.083333 0.083333
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+
+
+ 5.354555983000000 .000000000000000 .000000000000000
+ .000000000000000 5.354555983000000 .000000000000000
+ .000000000000000 .000000000000000 5.354555983000000
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+ 1.000/2.000 1.000/2.000 1.000/2.000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.416667 0.416667 0.416667
+ 0.416667 0.416667 0.250000
+ 0.416667 0.416667 0.083333
+ 0.416667 0.250000 0.250000
+ 0.416667 0.250000 0.083333
+ 0.416667 0.083333 0.083333
+ 0.250000 0.250000 0.250000
+ 0.250000 0.250000 0.083333
+ 0.250000 0.083333 0.083333
+ 0.083333 0.083333 0.083333
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/files/relaxxml/Fe_relax.xml b/tests/files/relaxxml/Fe_relax.xml
new file mode 100644
index 000000000..5ef8a9cc3
--- /dev/null
+++ b/tests/files/relaxxml/Fe_relax.xml
@@ -0,0 +1,13 @@
+
+
+
+ 0.0000000000 -0.0000000000 -0.0000000000
+ 0.0000000000 0.0000000000 -0.0000000000
+
+
+
+ 0.0000000000 0.0000000000 0.0000000000 0.0000000000 -0.0000000000 -0.0000000000
+ 2.6772779915 2.6772779915 2.6772779915 0.0000000000 0.0000000000 -0.0000000000
+
+
+
diff --git a/tests/old_todo/data/fleurinpmodifier/btest_fleurinpmodifier_py.back b/tests/old_todo/data/fleurinpmodifier/btest_fleurinpmodifier_py.back
deleted file mode 100644
index b06a01104..000000000
--- a/tests/old_todo/data/fleurinpmodifier/btest_fleurinpmodifier_py.back
+++ /dev/null
@@ -1,114 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-"""
-This test tries to create a fleurinpdata and to modefy it
-"""
-from __future__ import absolute_import
-from __future__ import print_function
-from aiida.orm import ParameterData
-import time
-import os
-from lxml import etree
-from pprint import pprint
-from aiida_fleur.data.fleurinpmodifier import FleurinpModifier
-from aiida.plugins import DataFactory
-from aiida_fleur.data.fleurinp import FleurinpData
-from aiida import load_dbenv, is_dbenv_loaded
-if not is_dbenv_loaded():
- load_dbenv()
-
-start_time = time.time()
-
-# schemanameQq
-
-path = os.getcwd() # path.realpath(__file__)
-print(path)
-filepath = path + '/inp.xml'
-# '/Users/broeder/aiida/scratch/broeder/aiida_run2/ff/4c/c14d-8a1b-40b3-af95-400e23002bcb/inp.xml'
-
-new_fleurinpData = FleurinpData(files=[filepath])
-# print(new_fleurinpData.get_file_abs_path('inp.xml'))
-# new_fleurinpData.store()
-
-#new_fleurinpData= load_node(6)
-
-fleurmode = FleurinpModifier(new_fleurinpData)
-
-#fleurmode.set_switch({'dos': True})
-
-fleurmode.set_inpchanges({})
-fleurmode.set_inpchanges({'dos': True})
-tria = True
-nkpts = 800
-
-change_dict = {'dos': True, 'ndir': -1, 'minEnergy': -0.8, 'maxEnergy': 0.8, 'sigma': 0.005}
-
-fleurmode.set_inpchanges(change_dict)
-if tria:
- change_dict = {'mode': 'tria'}
- fleurmode.set_inpchanges(change_dict)
-if nkpts:
- fleurmode.set_nkpts(count=nkpts)
-'''
-fleurmode.set_species('W-1', {'radius' : 3.5})
-fleurmode.change_atom('forces', True, position=(0.0, 0.0, 0.0))
-fleurmode.set_xpath('/fleurinput/@dos', True)
-'''
-'''
-name = 'Na-1'
-xpathn = '/fleurInput/atomSpecies/species[@name = "{}"]/mtSphere'.format(name)# 'radius':
-attributename = 'radius'
-attribv = 0.0000
-fleurmode.xml_set_all_attribv(xpathn, attributename, attribv)
-
-xpathn = '/fleurInput/atomSpecies/species/mtSphere'
-xpathn = '/fleurInput'
-#attribv = [0.0000, '1.2', 3.4]
-#fleurmode.xml_set_all_attribv(xpathn, attributename, attribv)
-
-
-#fleurmode.xml_set_attribv_occ(xmltree, xpathn, attributename, attribv, occ=[0])
-#fleurmode.xml_set_first_attribv(xmltree, xpathn, attributename, attribv)
-xpathn = '/fleurInput/atomSpecies/species[@name = "{}"]/mtSphere/@radius'.format(name)# 'radius':
-
-attribv = 1.1111
-#set_xpath(xmltree, xpathn, attribv)# does not work
-
-
-xpathn = '/fleurInput/atomGroups/atomGroup/relPos'
-text = '1.20000 PI/3 5.1-MYCrazyCostant'
-#fleurmode.xml_set_all_text(xpathn, text)
-
-
-fleurmode.set_species('Na-1', { 'mtSphere' : {'radius' : 3.5}})
-fleurmode.set_species('W-2', {'atomicCutoffs' : {'lmax' : 9, 'lnonsphr': 7}, 'energyParameters': {'d' : 6}, 'mtSphere' : {'radius' : 2.6, 'gridPoints' : 925, 'logIncrement' : .01800000}})
-print 'here1'
-#
-fleurmode.set_species('W-2', {'electronConfig' : {'coreConfig' : '[Xe] (4f5/2) (4f7/2)', 'valenceConfig' : '(6s1/2) (5d3/2) (5d5/2) (6p1/2) (6p3/2)'}}, create=True)#, 'stateOccupation' : [{'state' : "(6p3/2)", 'spinUp' : "1.00000000", 'spinDown' : "1.00000000"}, {'state' : "(6p1/2)", 'spinUp' : "1.00000000", 'spinDown' : "1.00000000"}]}}, create=True)
-
-
-xpathn = '/fleurInput/atomSpecies/species[@name = "{}"]'.format(name)# 'radius':
-xpathn2 = '/fleurInput/atomSpecies/species[@name = "{}"]/electronConfig3/e/d/g/f/yeah'.format(name)
-
-new_e = etree.Element('lo')
-new_e.set('type', "SCLO")
-
-#fleurmode.create_tag(xpathn, new_e, True)
-#fleurmode.create_tag(xpathn,'electronConfig2', True)
-
-#eval_xpath3(root, xpathn2, create=True)
-#fleurmode.set_species('W-2', {'lo': {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 1}}, True)
-
-#fleurmode.set_species('W-2', {'lo': [{'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 2}]}, True)
-#fleurmode.set_species('W-2', {'lo': [{'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 3}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 4}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 5}, {'type':"SCLO", 'l' : 1, 'n' : 5, 'eDeriv' : 6}]}, True)
-'''
-
-# fleurmode.changes()
-fleurmode.show(validate=True) # , display=False)
-
-print(fleurmode._original)
-print(fleurmode._tasks)
-out = '' # fleurmode.freeze()
-
-print('out: {}'.format(out))
-print('in: {}'.format(new_fleurinpData))
diff --git a/tests/old_todo/util/36.dot b/tests/old_todo/util/36.dot
deleted file mode 100644
index 8126966e4..000000000
--- a/tests/old_todo/util/36.dot
+++ /dev/null
@@ -1,4 +0,0 @@
-digraph G {
- N36 [shape=ellipse,label="StructureData (36)
-Cr",color="lightblue",style="filled"];
-}
diff --git a/tests/old_todo/util/btest_create_corehole_py.back b/tests/old_todo/util/btest_create_corehole_py.back
deleted file mode 100644
index bfec885fa..000000000
--- a/tests/old_todo/util/btest_create_corehole_py.back
+++ /dev/null
@@ -1,101 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-
-from __future__ import absolute_import
-from __future__ import print_function
-__copyright__ = (u'Copyright (c), 2016, Forschungszentrum Jülich GmbH, ' 'IAS-1/PGI-1, Germany. All rights reserved.')
-__license__ = 'MIT license, see LICENSE.txt file'
-__version__ = '0.27'
-__contributors__ = 'Jens Broeder'
-
-from aiida import load_dbenv, is_dbenv_loaded
-if not is_dbenv_loaded():
- load_dbenv()
-import sys, os
-from aiida.orm.querybuilder import QueryBuilder
-
-from aiida_fleur_ad.util.create_corehole import create_corehole, create_corehole_fleurinp, write_change
-from aiida_fleur.data.fleurinp import FleurinpData
-from aiida.plugins import Code, CalculationFactory, DataFactory
-from aiida.orm import load_node
-from pprint import pprint
-from aiida_fleur.tools.StructureData_util import break_symmetry as bs
-
-from aiida.orm import StructureData
-'''
-ids = [13586, 13934, 12748]#, 12927]
-
-for id in ids:
- s = load_node(id)
- new_s = bs(s, atoms=['Be'], site=[0, 1], pos=[(0.0, 0.0, -1.83792744752922), (0.0, 0.0, 0.918963723764612)])
- #new_s.store()
-'''
-#s = load_node(355)
-
-ids = [] #13924]#, 13925]#, 13926, 13927, 13928, 13929, 13930, 13931, 13932, 13933, 13934, 13935]
-#ids = [479, 480, 481, 482, 537]# O12W4, O12W4, O6W2, O6W2, O36W3Y18
-
-kind = 'W1'
-econfig = '[Kr] 5s2 4d10 4f13 | 5p6 5d5 6s2'
-para1 = Dict(
- dict={
- 'title': 'A test calculation of Tungsten',
- 'input': {
- 'film': False,
- 'cartesian': True,
- },
- 'atom': {
- 'element': 'W',
- 'jri': 833,
- 'rmt': 2.3,
- 'dx': 0.015,
- 'lmax': 8,
- 'lo': '5p',
- 'econfig': '[Kr] 5s2 4d10 4f14| 5p6 5d4 6s2',
- },
- 'soc': {
- 'theta': 0.0,
- 'phi': 0.0
- },
- 'comp': {
- 'kmax': 3.5,
- 'gmax': 2.9,
- },
- 'kpt': {
- 'nkpt': 200,
- }
- })
-#para1.store()
-#pprint(para1.get_dict())
-
-for id in ids:
- s = load_node(id)
- new_s, para = bs(s, atoms=[], site=[0, 1], pos=[(0.0, 0.0, 0, 0)], parameterData=para1)
- #print new_s.sites
- #pprint(para.get_dict())
- res = create_corehole(new_s, kind, econfig, para)
- #print res
- #pprint(para.get_dict())
- #pprint(res.get_dict())
-
-# test create_corehole_fleurinp
-#fleurinp = load_node(14039) # W film
-
-inpxmlfile1 = '../inp_xml_files/W/inp.xml'
-inpxmlfile = os.path.abspath(inpxmlfile1)
-fleurinp = FleurinpData(files=[inpxmlfile])
-species = 'W-1'
-stateocc = {'(5d3/2)': (2.5, 0.0), '(4f7/2)': (3.5, 4.0)}
-pos = []
-coreconfig = 'same'
-valenceconfig = 'same'
-#pprint(fleurinp.inp_dict)
-
-new_inp = create_corehole_fleurinp(fleurinp, species, stateocc)
-print(new_inp)
-
-etree = ''
-change = [(1, 2)]
-res = write_change(etree, change)
-#res.write('.outtree')
-print(res)
diff --git a/tests/old_todo/util/btest_read_cif_folder.py b/tests/old_todo/util/btest_read_cif_folder.py
deleted file mode 100644
index de9c75e59..000000000
--- a/tests/old_todo/util/btest_read_cif_folder.py
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-'''Implement a test for this interface'''
-from __future__ import absolute_import
-from aiida import load_dbenv, is_dbenv_loaded
-if not is_dbenv_loaded():
- load_dbenv()
-from aiida_fleur.tools.read_cif_folder import read_cif_folder
-
-read_cif_folder(log=True,
- store=True,
- recursive=True,
- extras={
- 'type': 'bulk',
- 'project': 'Fusion',
- 'specification': 'aiida_work',
- 'comment': 'Materials for Fusion'
- })
diff --git a/tests/parsers/fixtures/fleur/complex_errorout/out.error b/tests/parsers/fixtures/fleur/complex_errorout/out.error
new file mode 100644
index 000000000..cc8ea98a2
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/complex_errorout/out.error
@@ -0,0 +1,18 @@
+/O warning : failed to load external entity "relax.xml"
+**************juDFT-Error*****************
+Error message:Allocation of memmory failed for mat datatype
+Hint:You probably run out of memory
+*****************************************
+ Last kown location:
+ Last timer:Setup of H&S matrices
+ Timerstack:
+ Timer:eigen
+ Timer:gen. of hamil. and diag. (total)
+ Timer:Iteration
+ Timer:Total Run
+ *****************************************
+Rank:0 used 2.093GB/ 3412936 kB
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 873 100 101 100 772 257 1966 --:--:-- --:--:-- --:--:-- 1969
+juDFT-STOPPED
diff --git a/tests/parsers/fixtures/fleur/complex_errorout/out.xml b/tests/parsers/fixtures/fleur/complex_errorout/out.xml
new file mode 100644
index 000000000..4542bb57d
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/complex_errorout/out.xml
@@ -0,0 +1,140 @@
+
+
+
+
+
+ GEN
+
+
+
+
+
+
+
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+
+
+ 28.345891875000000 .000000000000000 .000000000000000
+ .000000000000000 28.345891875000000 .000000000000000
+ .000000000000000 .000000000000000 28.345891875000000
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+ -1.000/15.000 .0000000000 -.0266666667
+
+
+
+
+ 1.000/30.000 .0577350267 -.0266666667
+ 1.000/30.000 -.0577350267 -.0266666667
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/complex_errorout/shell.out b/tests/parsers/fixtures/fleur/complex_errorout/shell.out
new file mode 100644
index 000000000..3d16af8e6
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/complex_errorout/shell.out
@@ -0,0 +1,8 @@
+iffcluster0105: Using InfiniBand for MPI communication.
+ Welcome to FLEUR (www.flapw.de)
+ MaX-Release 4.0 (www.max-centre.eu)
+ stars are always ordered
+ --------------------------------------------------------
+ Number of OMP-threads: 12
+ --------------------------------------------------------
+ Usage data send using curl: usage.json
diff --git a/tests/parsers/fixtures/fleur/complex_errorout/usage.json b/tests/parsers/fixtures/fleur/complex_errorout/usage.json
new file mode 100644
index 000000000..688d6fe67
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/complex_errorout/usage.json
@@ -0,0 +1,31 @@
+{
+ "url":"www.flapw.de/collect.pl",
+ "calculation-id":"F6674BD6CD51AA09",
+ "data": {
+ "githash":"9cddd6d3ed47288c8d096c3f755728090cc6dc36",
+ "XC-treatment":2,
+ "MPI-PE":1,
+ "OMP":12,
+ "A-Types":3,
+ "Atoms":4,
+ "Real":false,
+ "Spins":1,
+ "Noco":false,
+ "SOC":false,
+ "SpinSpiral":false,
+ "PlaneWaves":47937,
+ "LOs":0,
+ "nkpt":1,
+ "gpu_per_node":0,
+ "Runtime":39.00,
+ "Error":"Allocation of memmory failed for mat datatype",
+ "cpu_model":"44",
+ "cpu_modelname":"Intel(R) Xeon(R) CPU X5670 @ 2.93GHz",
+ "VmPeak":3412936,
+ "VmSize":2194828,
+ "VmData":1614740,
+ "VmStk":350524,
+ "VmExe":12428,
+ "VmSwap":0
+ }
+}
diff --git a/tests/parsers/fixtures/fleur/default/JUDFT_WARN_ONLY b/tests/parsers/fixtures/fleur/default/JUDFT_WARN_ONLY
new file mode 100644
index 000000000..65c71eb10
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/JUDFT_WARN_ONLY
@@ -0,0 +1 @@
+/n
diff --git a/tests/parsers/fixtures/fleur/default/_scheduler-stderr.txt b/tests/parsers/fixtures/fleur/default/_scheduler-stderr.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/fixtures/fleur/default/_scheduler-stdout.txt b/tests/parsers/fixtures/fleur/default/_scheduler-stdout.txt
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/fixtures/fleur/default/cdn1 b/tests/parsers/fixtures/fleur/default/cdn1
new file mode 100644
index 000000000..2a3a43854
Binary files /dev/null and b/tests/parsers/fixtures/fleur/default/cdn1 differ
diff --git a/tests/parsers/fixtures/fleur/default/inp.xml b/tests/parsers/fixtures/fleur/default/inp.xml
new file mode 100644
index 000000000..4d34c362a
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/inp.xml
@@ -0,0 +1,368 @@
+
+
+
+ Si, alpha silicon, bulk, delta project
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.437500 0.437500 0.437500
+ 0.312500 0.437500 0.437500
+ 0.187500 0.437500 0.437500
+ 0.062500 0.437500 0.437500
+ 0.062500 0.500000 0.500000
+ 0.187500 0.562500 0.562500
+ 0.312500 0.562500 0.562500
+ 0.437500 0.437500 0.562500
+ 0.312500 0.312500 0.437500
+ 0.187500 0.312500 0.437500
+ 0.125000 0.375000 0.437500
+ 0.125000 0.437500 0.500000
+ 0.187500 0.500000 0.625000
+ 0.312500 0.437500 0.687500
+ 0.312500 0.437500 0.562500
+ 0.250000 0.250000 0.437500
+ 0.250000 0.375000 0.437500
+ 0.250000 0.437500 0.500000
+ 0.250000 0.437500 0.625000
+ 0.250000 0.500000 0.687500
+ 0.187500 0.437500 0.562500
+ 0.375000 0.375000 0.437500
+ 0.375000 0.437500 0.500000
+ 0.375000 0.437500 0.625000
+ 0.250000 0.562500 0.625000
+ 0.125000 0.500000 0.562500
+ 0.437500 0.500000 0.500000
+ 0.375000 0.500000 0.562500
+ 0.250000 0.500000 0.562500
+ 0.375000 0.375000 0.562500
+ 0.250000 0.375000 0.562500
+ 0.312500 0.312500 0.562500
+ 0.312500 0.312500 0.312500
+ 0.187500 0.312500 0.312500
+ 0.062500 0.312500 0.312500
+ 0.062500 0.375000 0.375000
+ 0.187500 0.500000 0.500000
+ 0.375000 0.375000 0.687500
+ 0.187500 0.187500 0.312500
+ 0.125000 0.250000 0.312500
+ 0.125000 0.312500 0.375000
+ 0.187500 0.375000 0.500000
+ 0.312500 0.500000 0.625000
+ 0.250000 0.250000 0.312500
+ 0.250000 0.312500 0.375000
+ 0.250000 0.312500 0.500000
+ 0.312500 0.375000 0.625000
+ 0.312500 0.375000 0.375000
+ 0.312500 0.375000 0.500000
+ 0.312500 0.500000 0.500000
+ 0.187500 0.187500 0.187500
+ 0.062500 0.187500 0.187500
+ 0.062500 0.250000 0.250000
+ 0.187500 0.375000 0.375000
+ 0.125000 0.125000 0.187500
+ 0.125000 0.187500 0.250000
+ 0.187500 0.250000 0.375000
+ 0.187500 0.250000 0.250000
+ 0.062500 0.062500 0.062500
+ 0.062500 0.125000 0.125000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+
+
+ .000000000000000 5.167355275200000 5.167355275200000
+ 5.167355275200000 .000000000000000 5.167355275200000
+ 5.167355275200000 5.167355275200000 .000000000000000
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ 1.000/8.000 1.000/8.000 1.000/8.000
+ -1.000/8.000 -1.000/8.000 -1.000/8.000
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/default/juDFT_times.json b/tests/parsers/fixtures/fleur/default/juDFT_times.json
new file mode 100644
index 000000000..c3ad98c14
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/juDFT_times.json
@@ -0,0 +1,434 @@
+{
+ "timername" : "Total Run",
+ "totaltime" : 4.00000,
+ "subtimers": [
+ {
+ "timername" : "Initialization",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1,
+ "subtimers": [
+ {
+ "timername" : "r_inpXML",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ },
+ {
+ "timername" : "postprocessInput",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1,
+ "subtimers": [
+ {
+ "timername" : "strgn",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1,
+ "subtimers": [
+ {
+ "timername" : "writeStars",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ }
+ ]
+ },
+ {
+ "timername" : "stepf",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "timername" : "generation of start-density",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1,
+ "subtimers": [
+ {
+ "timername" : "qpw_to_nmt",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ },
+ {
+ "timername" : "cdntot",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1,
+ "subtimers": [
+ {
+ "timername" : "MT",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "timername" : "Qfix",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ },
+ {
+ "timername" : "Open file/memory for IO of eig",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 1
+ },
+ {
+ "timername" : "Iteration",
+ "totaltime" : 4.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "generation of potential",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "psqpw",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "interstitial",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "MT-spheres",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "den-pot integrals",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Vxc in interstitial",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Vxc in MT",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ }
+ ]
+ },
+ {
+ "timername" : "gen. of hamil. and diag. (tota",
+ "totaltime" : 3.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "eigen",
+ "totaltime" : 3.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "Updating energy parameters",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "tlmplm",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Setup of H&S matrices",
+ "totaltime" : 2.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 660,
+ "subtimers": [
+ {
+ "timername" : "Interstitial part",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "MT part",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 660,
+ "subtimers": [
+ {
+ "timername" : "fjgj coefficients",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "spherical setup",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "non-spherical setup",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "LO setup",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ }
+ ]
+ },
+ {
+ "timername" : "Matrix redistribution",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ }
+ ]
+ },
+ {
+ "timername" : "Diagonalization",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "EV output",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660,
+ "subtimers": [
+ {
+ "timername" : "IO (write)",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "timername" : "determination of fermi energy",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "IO (read)",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "IO (write)",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ }
+ ]
+ },
+ {
+ "timername" : "generation of new charge densi",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "cdnval",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "IO (read)",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "pwden",
+ "totaltime" : 1.00000,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 1.00000,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "abcof",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "cdnval: rhomt",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "cdnval: rhonmt",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "cdnval: rho(n)mtlo",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 660
+ },
+ {
+ "timername" : "cdnmt",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ }
+ ]
+ },
+ {
+ "timername" : "cdntot",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 22,
+ "subtimers": [
+ {
+ "timername" : "MT",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 22
+ }
+ ]
+ },
+ {
+ "timername" : "cdngen: cdncore",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "qpw_to_nmt",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ }
+ ]
+ }
+ ]
+ },
+ {
+ "timername" : "determination of total energy",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Charge Density Mixing",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11,
+ "subtimers": [
+ {
+ "timername" : "Reading of distances",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Mixing",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ },
+ {
+ "timername" : "Postprocessing",
+ "totaltime" : 0.0000E+00,
+ "mintime" : 0.0000E+00,
+ "maxtime" : 0.0000E+00,
+ "ncalls" : 11
+ }
+ ]
+ }
+ ]
+ }
+ ]
+}
diff --git a/tests/parsers/fixtures/fleur/default/out.error b/tests/parsers/fixtures/fleur/default/out.error
new file mode 100644
index 000000000..af9803b54
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/out.error
@@ -0,0 +1,12 @@
+I/O warning : failed to load external entity "relax.xml"
+
+ *****************************************
+ Run finished successfully
+ Stop message:
+ all done
+ *****************************************
+Rank:0 used 0.676GB/ 712964 kB
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+
0 0 0 0 0 0 0 0 --:--:-- --:--:-- --:--:-- 0
100 780 100 40 100 740 181 3352 --:--:-- --:--:-- --:--:-- 3363
+OK
diff --git a/tests/parsers/fixtures/fleur/default/out.xml b/tests/parsers/fixtures/fleur/default/out.xml
new file mode 100644
index 000000000..0fe9c6b19
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/out.xml
@@ -0,0 +1,1013 @@
+
+
+
+
+
+ GEN
+
+
+
+
+
+
+
+
+
+ Si, alpha silicon, bulk, delta project
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.437500 0.437500 0.437500
+ 0.312500 0.437500 0.437500
+ 0.187500 0.437500 0.437500
+ 0.062500 0.437500 0.437500
+ 0.062500 0.500000 0.500000
+ 0.187500 0.562500 0.562500
+ 0.312500 0.562500 0.562500
+ 0.437500 0.437500 0.562500
+ 0.312500 0.312500 0.437500
+ 0.187500 0.312500 0.437500
+ 0.125000 0.375000 0.437500
+ 0.125000 0.437500 0.500000
+ 0.187500 0.500000 0.625000
+ 0.312500 0.437500 0.687500
+ 0.312500 0.437500 0.562500
+ 0.250000 0.250000 0.437500
+ 0.250000 0.375000 0.437500
+ 0.250000 0.437500 0.500000
+ 0.250000 0.437500 0.625000
+ 0.250000 0.500000 0.687500
+ 0.187500 0.437500 0.562500
+ 0.375000 0.375000 0.437500
+ 0.375000 0.437500 0.500000
+ 0.375000 0.437500 0.625000
+ 0.250000 0.562500 0.625000
+ 0.125000 0.500000 0.562500
+ 0.437500 0.500000 0.500000
+ 0.375000 0.500000 0.562500
+ 0.250000 0.500000 0.562500
+ 0.375000 0.375000 0.562500
+ 0.250000 0.375000 0.562500
+ 0.312500 0.312500 0.562500
+ 0.312500 0.312500 0.312500
+ 0.187500 0.312500 0.312500
+ 0.062500 0.312500 0.312500
+ 0.062500 0.375000 0.375000
+ 0.187500 0.500000 0.500000
+ 0.375000 0.375000 0.687500
+ 0.187500 0.187500 0.312500
+ 0.125000 0.250000 0.312500
+ 0.125000 0.312500 0.375000
+ 0.187500 0.375000 0.500000
+ 0.312500 0.500000 0.625000
+ 0.250000 0.250000 0.312500
+ 0.250000 0.312500 0.375000
+ 0.250000 0.312500 0.500000
+ 0.312500 0.375000 0.625000
+ 0.312500 0.375000 0.375000
+ 0.312500 0.375000 0.500000
+ 0.312500 0.500000 0.500000
+ 0.187500 0.187500 0.187500
+ 0.062500 0.187500 0.187500
+ 0.062500 0.250000 0.250000
+ 0.187500 0.375000 0.375000
+ 0.125000 0.125000 0.187500
+ 0.125000 0.187500 0.250000
+ 0.187500 0.250000 0.375000
+ 0.187500 0.250000 0.250000
+ 0.062500 0.062500 0.062500
+ 0.062500 0.125000 0.125000
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+ 0 -1 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 -1 -1 .5000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 1 1 1 .5000000000
+
+
+ -1 -1 -1 .5000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 -1 -1 .5000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ 1 1 1 .5000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 1 1 1 .5000000000
+
+
+
+
+ .000000000000000 5.167355275200000 5.167355275200000
+ 5.167355275200000 .000000000000000 5.167355275200000
+ 5.167355275200000 5.167355275200000 .000000000000000
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ 1.000/8.000 1.000/8.000 1.000/8.000
+ -1.000/8.000 -1.000/8.000 -1.000/8.000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.437500 0.437500 0.437500
+ 0.312500 0.437500 0.437500
+ 0.187500 0.437500 0.437500
+ 0.062500 0.437500 0.437500
+ 0.062500 0.500000 0.500000
+ 0.187500 0.562500 0.562500
+ 0.312500 0.562500 0.562500
+ 0.437500 0.437500 0.562500
+ 0.312500 0.312500 0.437500
+ 0.187500 0.312500 0.437500
+ 0.125000 0.375000 0.437500
+ 0.125000 0.437500 0.500000
+ 0.187500 0.500000 0.625000
+ 0.312500 0.437500 0.687500
+ 0.312500 0.437500 0.562500
+ 0.250000 0.250000 0.437500
+ 0.250000 0.375000 0.437500
+ 0.250000 0.437500 0.500000
+ 0.250000 0.437500 0.625000
+ 0.250000 0.500000 0.687500
+ 0.187500 0.437500 0.562500
+ 0.375000 0.375000 0.437500
+ 0.375000 0.437500 0.500000
+ 0.375000 0.437500 0.625000
+ 0.250000 0.562500 0.625000
+ 0.125000 0.500000 0.562500
+ 0.437500 0.500000 0.500000
+ 0.375000 0.500000 0.562500
+ 0.250000 0.500000 0.562500
+ 0.375000 0.375000 0.562500
+ 0.250000 0.375000 0.562500
+ 0.312500 0.312500 0.562500
+ 0.312500 0.312500 0.312500
+ 0.187500 0.312500 0.312500
+ 0.062500 0.312500 0.312500
+ 0.062500 0.375000 0.375000
+ 0.187500 0.500000 0.500000
+ 0.375000 0.375000 0.687500
+ 0.187500 0.187500 0.312500
+ 0.125000 0.250000 0.312500
+ 0.125000 0.312500 0.375000
+ 0.187500 0.375000 0.500000
+ 0.312500 0.500000 0.625000
+ 0.250000 0.250000 0.312500
+ 0.250000 0.312500 0.375000
+ 0.250000 0.312500 0.500000
+ 0.312500 0.375000 0.625000
+ 0.312500 0.375000 0.375000
+ 0.312500 0.375000 0.500000
+ 0.312500 0.500000 0.500000
+ 0.187500 0.187500 0.187500
+ 0.062500 0.187500 0.187500
+ 0.062500 0.250000 0.250000
+ 0.187500 0.375000 0.375000
+ 0.125000 0.125000 0.187500
+ 0.125000 0.187500 0.250000
+ 0.187500 0.250000 0.375000
+ 0.187500 0.250000 0.250000
+ 0.062500 0.062500 0.062500
+ 0.062500 0.125000 0.125000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/default/shell.out b/tests/parsers/fixtures/fleur/default/shell.out
new file mode 100644
index 000000000..39ea32f54
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/default/shell.out
@@ -0,0 +1,58 @@
+ Welcome to FLEUR (www.flapw.de)
+ MaX-Release 4.0 (www.max-centre.eu)
+ stars are always ordered
+ --------------------------------------------------------
+ Number of OMP-threads: 6
+ --------------------------------------------------------
+ Iteration: 1 Distance: 8.14211820818857
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 2 Distance: 7.69204733499305
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 3 Distance: 0.856944507774482
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 4 Distance: 0.501438298333166
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 5 Distance: 0.205605182835176
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 6 Distance: 1.852288794887397E-002
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 7 Distance: 1.291466956872122E-002
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 8 Distance: 1.303177341130901E-003
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 9 Distance: 1.207653876674686E-003
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 10 Distance: 1.741120625902552E-004
+ Test for time of next iteration:
+ Time provided (min): 10
+ Time used (min): 1
+ Time per iter (min): 1
+ Iteration: 11 Distance: 3.295348349644261E-005
+ Usage data send using curl: usage.json
diff --git a/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.error b/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.error
new file mode 100644
index 000000000..e11603cde
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.error
@@ -0,0 +1,16 @@
+**************juDFT-Error*****************
+Error message:Overlapping MT-spheres during relaxation:
+2 1 olap: 6.8200E-03
+Treat as an error: writing rescaled displacements to relax.xml is not implemented
+*****************************************
+ Last kown location:
+ Last timer:postprocessInput
+ Timerstack:
+ Timer:Initialization
+ Timer:Total Run
+ *****************************************
+Rank:0 used 0.171GB/ 178892 kB
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 697 100 101 100 596 295 1745 --:--:-- --:--:-- --:--:-- 1747
+juDFT-STOPPED
diff --git a/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.xml b/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.xml
new file mode 100644
index 000000000..4f4396841
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/mt_overlap_errorout/out.xml
@@ -0,0 +1,19 @@
+
+
+
+
+
+ GEN
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/mt_overlap_errorout/relax.xml b/tests/parsers/fixtures/fleur/mt_overlap_errorout/relax.xml
new file mode 100644
index 000000000..99be634d9
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/mt_overlap_errorout/relax.xml
@@ -0,0 +1,14 @@
+
+
+
+ 0.0000000000 0.0000000000 0.0246059526
+
+
+
+ 0.0000000000 0.0000000000 -0.7558904500 0.0000000000 0.0000000000 0.0283825580
+
+
+ 0.0000000000 0.0000000000 -0.7416991710 0.0000000000 0.0000000000 0.0208293472
+
+
+
diff --git a/tests/parsers/fixtures/fleur/mt_overlap_errorout/shell.out b/tests/parsers/fixtures/fleur/mt_overlap_errorout/shell.out
new file mode 100644
index 000000000..20176599a
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/mt_overlap_errorout/shell.out
@@ -0,0 +1,6 @@
+iffcluster0111: Using InfiniBand for MPI communication.
+ Welcome to FLEUR (www.flapw.de)
+ MaX-Release 4.0 (www.max-centre.eu)
+ Attention: Overlapping MT-spheres. Reduced displacement by 10%
+ 2 1 6.819998745005051E-003
+ Usage data send using curl: usage.json
diff --git a/tests/parsers/fixtures/fleur/relax/inp.xml b/tests/parsers/fixtures/fleur/relax/inp.xml
new file mode 100644
index 000000000..0c4cd2a6f
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/relax/inp.xml
@@ -0,0 +1,151 @@
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+
+
+ 28.345891875000000 .000000000000000 .000000000000000
+ .000000000000000 28.345891875000000 .000000000000000
+ .000000000000000 .000000000000000 28.345891875000000
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 -.7558904500
+ .0000000000 .0000000000 .7558904500
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/relax/out.error b/tests/parsers/fixtures/fleur/relax/out.error
new file mode 100644
index 000000000..8fd25387b
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/relax/out.error
@@ -0,0 +1,10 @@
+ *****************************************
+ Run finished successfully
+ Stop message:
+ Structural relaxation: new displacements generated
+ *****************************************
+Rank:0 used 2.394GB/ 4967856 kB
+ % Total % Received % Xferd Average Speed Time Time Time Current
+ Dload Upload Total Spent Left Speed
+100 807 100 74 100 733 191 1897 --:--:-- --:--:-- --:--:-- 1894
+OK
diff --git a/tests/parsers/fixtures/fleur/relax/out.xml b/tests/parsers/fixtures/fleur/relax/out.xml
new file mode 100644
index 000000000..82e5d56bb
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/relax/out.xml
@@ -0,0 +1,2317 @@
+
+
+
+
+
+ GEN
+
+
+
+
+
+
+
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+
+
+ 28.345891875000000 .000000000000000 .000000000000000
+ .000000000000000 28.345891875000000 .000000000000000
+ .000000000000000 .000000000000000 4.630000000000000
+
+
+
+ |
+
+
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 -.7416991710
+ .0000000000 .0000000000 .7416991710
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/fleur/relax/relax.xml b/tests/parsers/fixtures/fleur/relax/relax.xml
new file mode 100644
index 000000000..99be634d9
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/relax/relax.xml
@@ -0,0 +1,14 @@
+
+
+
+ 0.0000000000 0.0000000000 0.0246059526
+
+
+
+ 0.0000000000 0.0000000000 -0.7558904500 0.0000000000 0.0000000000 0.0283825580
+
+
+ 0.0000000000 0.0000000000 -0.7416991710 0.0000000000 0.0000000000 0.0208293472
+
+
+
diff --git a/tests/parsers/fixtures/fleur/relax/shell.out b/tests/parsers/fixtures/fleur/relax/shell.out
new file mode 100644
index 000000000..333823046
--- /dev/null
+++ b/tests/parsers/fixtures/fleur/relax/shell.out
@@ -0,0 +1,214 @@
+iffcluster0107: Using InfiniBand for MPI communication.
+ Welcome to FLEUR (www.flapw.de)
+ MaX-Release 4.0 (www.max-centre.eu)
+ nop = 16
+ --------------------------------------------------------
+ Number of OMP-threads: 12
+ --------------------------------------------------------
+ Iteration: 1 Distance: 0.163237983230284
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 4
+ Time per iter (min): 4
+ Iteration: 2 Distance: 0.152278301128890
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 8
+ Time per iter (min): 4
+ Iteration: 3 Distance: 1.280699031885719E-002
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 11
+ Time per iter (min): 4
+ Iteration: 4 Distance: 1.544701303213275E-002
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 15
+ Time per iter (min): 4
+ Iteration: 5 Distance: 4.020987856830026E-003
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 19
+ Time per iter (min): 4
+ Iteration: 6 Distance: 1.945253362703284E-004
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 23
+ Time per iter (min): 4
+ Iteration: 7 Distance: 2.468709825867029E-004
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 26
+ Time per iter (min): 4
+ Iteration: 8 Distance: 1.028491110414090E-004
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 30
+ Time per iter (min): 4
+ Iteration: 9 Distance: 9.929615259078387E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 34
+ Time per iter (min): 4
+ Iteration: 10 Distance: 3.876139978531418E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 38
+ Time per iter (min): 4
+ Iteration: 11 Distance: 5.192625893104915E-006
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 41
+ Time per iter (min): 4
+ Iteration: 12 Distance: 9.189232451067283E-006
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 45
+ Time per iter (min): 4
+ Iteration: 13 Distance: 2.783739128832825E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 49
+ Time per iter (min): 4
+ Iteration: 14 Distance: 4.212128520807909E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 53
+ Time per iter (min): 4
+ Iteration: 15 Distance: 7.731771252447340E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 57
+ Time per iter (min): 4
+ Iteration: 16 Distance: 7.768845617471034E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 61
+ Time per iter (min): 4
+ Iteration: 17 Distance: 7.341253721698628E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 65
+ Time per iter (min): 4
+ Iteration: 18 Distance: 3.526433224843018E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 69
+ Time per iter (min): 4
+ Iteration: 19 Distance: 6.266528245181366E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 73
+ Time per iter (min): 4
+ Iteration: 20 Distance: 7.731238834573022E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 77
+ Time per iter (min): 4
+ Iteration: 21 Distance: 3.388841940099947E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 81
+ Time per iter (min): 4
+ Iteration: 22 Distance: 3.230813132151605E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 85
+ Time per iter (min): 4
+ Iteration: 23 Distance: 3.288678618197010E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 89
+ Time per iter (min): 4
+ Iteration: 24 Distance: 2.973785652738386E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 94
+ Time per iter (min): 4
+ Iteration: 25 Distance: 2.924083584706251E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 98
+ Time per iter (min): 4
+ Iteration: 26 Distance: 2.913527221808891E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 102
+ Time per iter (min): 4
+ Iteration: 27 Distance: 2.999922005973378E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 106
+ Time per iter (min): 4
+ Iteration: 28 Distance: 3.008806094258066E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 110
+ Time per iter (min): 4
+ Iteration: 29 Distance: 3.504814074016484E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 115
+ Time per iter (min): 4
+ Iteration: 30 Distance: 3.338360515741878E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 119
+ Time per iter (min): 4
+ Iteration: 31 Distance: 3.842254803335153E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 123
+ Time per iter (min): 4
+ Iteration: 32 Distance: 4.627627754515800E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 128
+ Time per iter (min): 4
+ Iteration: 33 Distance: 4.311438958929168E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 132
+ Time per iter (min): 4
+ Iteration: 34 Distance: 4.488399890836128E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 137
+ Time per iter (min): 5
+ Iteration: 35 Distance: 4.932233829957257E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 141
+ Time per iter (min): 5
+ Iteration: 36 Distance: 3.389671397825875E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 146
+ Time per iter (min): 5
+ Iteration: 37 Distance: 1.990699684397925E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 150
+ Time per iter (min): 5
+ Iteration: 38 Distance: 2.212929999310191E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 155
+ Time per iter (min): 5
+ Iteration: 39 Distance: 2.515473192069385E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 159
+ Time per iter (min): 5
+ Iteration: 40 Distance: 1.265346941883755E-005
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 164
+ Time per iter (min): 5
+ Iteration: 41 Distance: 1.531689360592881E-006
+ Test for time of next iteration:
+ Time provided (min): 360
+ Time used (min): 168
+ Time per iter (min): 5
+ Reset of history
+ Usage data send using curl: usage.json
diff --git a/tests/parsers/fixtures/inpgen/broken_inpxml/inp.xml b/tests/parsers/fixtures/inpgen/broken_inpxml/inp.xml
new file mode 100644
index 000000000..a1dfec490
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/broken_inpxml/inp.xml
@@ -0,0 +1,111 @@
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ -0.000000 0.333333 0.333333
+ -0.333333 0.333333 0.333333
+ -0.000000 0.000000 0.333333
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 -1 0 .0000000000
+
diff --git a/tests/parsers/fixtures/inpgen/broken_inpxml/out b/tests/parsers/fixtures/inpgen/broken_inpxml/out
new file mode 100644
index 000000000..fca99897b
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/broken_inpxml/out
@@ -0,0 +1,687 @@
+line: 1>A Fleur input generator calculation with aiida
+line: 2>&input cartesian=F /
+line: 3>-3.0138120600 3.0138120600 3.0138120600
+line: 4>3.0138120600 -3.0138120600 3.0138120600
+line: 5>3.0138120600 3.0138120600 -3.0138120600
+line: 6>1.0000000000
+line: 7>1.0000000000 1.0000000000 1.0000000000
+line: 8>
+line: 9>1
+line: 10>74 0.0000000000 0.0000000000 0.0000000000
+line: 11>&atom
+line: 12>econfig="[Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4" element="W" jri=981 lm
+
+ A Fleur input generator calculation with aiida
+
+ film= F cartesian= F
+ checkinp= F symor= F
+
+a1 = -3.01381 3.01381 3.01381
+a2 = 3.01381 -3.01381 3.01381
+a3 = 3.01381 3.01381 -3.01381
+
+dvac= -3.01381 aa = 1.00000
+scale = 1.00000 1.00000 1.00000
+
+natin= 1 Z = 74
+ positions:
+ 0.00000 0.00000 0.00000
+
+ generators: 0 (excluding identity)
+
+
+ Lattice information:
+ --------------------
+
+ overall lattice constant a0 = 1.000000 bohr
+
+ real-space primitive lattice vectors in units of a_{x,y,z}
+ a_1: -3.013812 3.013812 3.013812
+ a_2: 3.013812 -3.013812 3.013812
+ a_3: 3.013812 3.013812 -3.013812
+
+ lattice constants a_x, a_y, a_z = 1.000000 1.000000 1.000000
+ volume of unit cell (a.u.^3) = 109.498581
+
+dbg: lattice matrices
+ 109.498580847925
+dbg: as :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bs :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: amat :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bmat :
+ 0.000000 0.521199 0.521199
+ 0.521199 0.000000 0.521199
+ 0.521199 0.521199 0.000000
+dbg: amatinv :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: aamat :
+ 27.249189 -9.083063 -9.083063
+ -9.083063 27.249189 -9.083063
+ -9.083063 -9.083063 27.249189
+dbg: bbmat :
+ 0.543297 0.271649 0.271649
+ 0.271649 0.543297 0.271649
+ 0.271649 0.271649 0.543297
+
+dbg: lattice vectors :
+vector 1 : -3.01381 3.01381 3.01381 length : 5.22008
+vector 2 : 3.01381 -3.01381 3.01381 length : 5.22008
+vector 3 : 3.01381 3.01381 -3.01381 length : 5.22008
+angle between vectors (1,2) =109.47122
+angle between vectors (1,3) =109.47122
+angle between vectors (2,3) =109.47122
+
+dbg: reciprocal lattice vectors :
+vector 1 : 0.00000 0.52120 0.52120 length : 0.73709
+vector 2 : 0.52120 0.00000 0.52120 length : 0.73709
+vector 3 : 0.52120 0.52120 0.00000 length : 0.73709
+angle between vectors (1,2) = 60.00000
+angle between vectors (1,3) = 60.00000
+angle between vectors (2,3) = 60.00000
+
+
+ Point group of the Bravais lattice has 48 operations
+
+ DBG: symor,zorth,oldfleur : T F F
+ DBG: optype : 1 -2 -2 3 3 -2 -2 3 2 -4 3 -4 -1 2 2 -3 -3 2 2 -2 -3 4 4 -3 -3 4 2 -3 -2 4 3 -2 -4 2 -4 3 3 -4 -4 3 -2 2 4 -3 -3 2 4 -2
+ DBG: invsym,invs,zrfs,invs2 : T T F F
+ DBG: (before reorder) invsop,zrfsop,invs2op : 13 7 46
+
+ Space group information:
+ ------------------------
+ 48 operations
+ space group is symmorphic
+ has inversion symmetry
+
+
+ Operations: (in International notation)
+ ---------------------------------------
+ lattice coordinates (scaled) Cartesian coordinates
+
+ operation 1: 1 (inverse = 1)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 2: 2 (inverse = 2)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 3: 2 (inverse = 3)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 4: 3 (inverse = 5)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 5: 3 (inverse = 4)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 6: 2 (inverse = 6)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 7: 2 (inverse = 7)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 8: 3 (inverse = 31)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 9: 2 (inverse = 9)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 10: 4 (inverse = 33)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 11: 3 (inverse = 37)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 12: 4 (inverse = 39)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 13: 1 (inverse = 13)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 14: 2 (inverse = 14)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 15: 2 (inverse = 15)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 16: 3 (inverse = 17)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 17: 3 (inverse = 16)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 18: 2 (inverse = 18)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 19: 2 (inverse = 19)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 20: 2 (inverse = 20)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 21: 3 (inverse = 25)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 22: 4 (inverse = 43)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+
+ operation 23: 4 (inverse = 26)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 24: 3 (inverse = 44)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 25: 3 (inverse = 21)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+
+ operation 26: 4 (inverse = 23)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+
+ operation 27: 2 (inverse = 27)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 28: 3 (inverse = 45)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 29: 2 (inverse = 29)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 30: 4 (inverse = 47)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 31: 3 (inverse = 8)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 32: 2 (inverse = 32)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 33: 4 (inverse = 10)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 34: 2 (inverse = 34)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 35: 4 (inverse = 38)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 36: 3 (inverse = 40)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 37: 3 (inverse = 11)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 38: 4 (inverse = 35)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 39: 4 (inverse = 12)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 40: 3 (inverse = 36)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 41: 2 (inverse = 41)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 42: 2 (inverse = 42)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 43: 4 (inverse = 22)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 44: 3 (inverse = 24)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 45: 3 (inverse = 28)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 46: 2 (inverse = 46)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ operation 47: 4 (inverse = 30)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 48: 2 (inverse = 48)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ Multiplcation table: {R_j|t_j}{R_i|t_i}
+ operation j= 1 : 1 2 3 4 5 6 7 8 9 10 11 12
+ 13 14 15 16 17 18 19 20 21 22 23 24
+ 25 26 27 28 29 30 31 32 33 34 35 36
+ 37 38 39 40 41 42 43 44 45 46 47 48
+ operation j= 2 : 2 1 5 6 3 4 31 32 33 34 35 36
+ 14 13 17 18 15 16 20 19 23 24 21 22
+ 43 44 45 46 47 48 7 8 9 10 11 12
+ 39 40 37 38 42 41 25 26 27 28 29 30
+ operation j= 3 : 3 4 1 2 6 5 37 38 39 40 41 42
+ 18 17 16 15 14 13 44 43 47 48 45 46
+ 26 25 29 30 27 28 33 34 31 32 36 35
+ 7 8 9 10 11 12 20 19 23 24 21 22
+ operation j= 4 : 4 3 6 5 1 2 33 34 31 32 36 35
+ 17 18 14 13 16 15 43 44 45 46 47 48
+ 20 19 23 24 21 22 37 38 39 40 41 42
+ 9 10 7 8 12 11 26 25 29 30 27 28
+ operation j= 5 : 5 6 2 1 4 3 39 40 37 38 42 41
+ 16 15 18 17 13 14 26 25 29 30 27 28
+ 44 43 47 48 45 46 9 10 7 8 12 11
+ 31 32 33 34 35 36 19 20 21 22 23 24
+ operation j= 6 : 6 5 4 3 2 1 9 10 7 8 12 11
+ 15 16 13 14 18 17 25 26 27 28 29 30
+ 19 20 21 22 23 24 39 40 37 38 42 41
+ 33 34 31 32 36 35 44 43 47 48 45 46
+ operation j= 7 : 7 8 11 12 10 9 1 2 6 5 3 4
+ 46 45 48 47 43 44 24 23 22 21 20 19
+ 30 29 28 27 26 25 32 31 36 35 34 33
+ 41 42 40 39 37 38 17 18 14 13 16 15
+ operation j= 8 : 8 7 10 9 11 12 32 31 36 35 34 33
+ 45 46 43 44 48 47 23 24 20 19 22 21
+ 17 18 14 13 16 15 1 2 6 5 3 4
+ 40 39 41 42 38 37 30 29 28 27 26 25
+ operation j= 9 : 9 10 12 11 8 7 6 5 1 2 4 3
+ 48 47 46 45 44 43 30 29 28 27 26 25
+ 24 23 22 21 20 19 40 39 41 42 38 37
+ 36 35 32 31 33 34 18 17 16 15 14 13
+ operation j=10 : 10 9 8 7 12 11 40 39 41 42 38 37
+ 47 48 44 43 46 45 29 30 26 25 28 27
+ 18 17 16 15 14 13 6 5 1 2 4 3
+ 32 31 36 35 34 33 24 23 22 21 20 19
+ operation j=11 : 11 12 7 8 9 10 41 42 40 39 37 38
+ 44 43 47 48 45 46 18 17 16 15 14 13
+ 29 30 26 25 28 27 36 35 32 31 33 34
+ 1 2 6 5 3 4 23 24 20 19 22 21
+ operation j=12 : 12 11 9 10 7 8 36 35 32 31 33 34
+ 43 44 45 46 47 48 17 18 14 13 16 15
+ 23 24 20 19 22 21 41 42 40 39 37 38
+ 6 5 1 2 4 3 29 30 26 25 28 27
+ operation j=13 : 13 14 18 17 16 15 46 45 48 47 44 43
+ 1 2 6 5 4 3 41 42 40 39 38 37
+ 36 35 32 31 34 33 28 27 30 29 26 25
+ 24 23 22 21 19 20 12 11 8 7 10 9
+ operation j=14 : 14 13 16 15 18 17 28 27 30 29 26 25
+ 2 1 4 3 6 5 42 41 38 37 40 39
+ 12 11 8 7 10 9 46 45 48 47 44 43
+ 22 21 24 23 20 19 36 35 32 31 34 33
+ operation j=15 : 15 16 17 18 14 13 48 47 46 45 43 44
+ 6 5 1 2 3 4 36 35 32 31 34 33
+ 41 42 40 39 38 37 22 21 24 23 20 19
+ 30 29 28 27 25 26 11 12 10 9 8 7
+ operation j=16 : 16 15 14 13 17 18 22 21 24 23 20 19
+ 5 6 3 4 1 2 35 36 34 33 32 31
+ 11 12 10 9 8 7 48 47 46 45 43 44
+ 28 27 30 29 26 25 41 42 40 39 38 37
+ operation j=17 : 17 18 15 16 13 14 30 29 28 27 25 26
+ 4 3 2 1 5 6 12 11 8 7 10 9
+ 42 41 38 37 40 39 24 23 22 21 19 20
+ 48 47 46 45 43 44 35 36 34 33 32 31
+ operation j=18 : 18 17 13 14 15 16 24 23 22 21 19 20
+ 3 4 5 6 2 1 11 12 10 9 8 7
+ 35 36 34 33 32 31 30 29 28 27 25 26
+ 46 45 48 47 44 43 42 41 38 37 40 39
+ operation j=19 : 19 20 24 23 22 21 44 43 47 48 46 45
+ 41 42 40 39 38 37 1 2 6 5 4 3
+ 32 31 36 35 33 34 26 25 29 30 28 27
+ 18 17 16 15 13 14 8 7 12 11 9 10
+ operation j=20 : 20 19 22 21 24 23 26 25 29 30 28 27
+ 42 41 38 37 40 39 2 1 4 3 6 5
+ 8 7 12 11 9 10 44 43 47 48 46 45
+ 16 15 18 17 14 13 32 31 36 35 33 34
+ operation j=21 : 21 22 23 24 20 19 47 48 44 43 45 46
+ 40 39 41 42 37 38 32 31 36 35 33 34
+ 1 2 6 5 4 3 16 15 18 17 14 13
+ 29 30 26 25 27 28 7 8 9 10 12 11
+ operation j=22 : 22 21 20 19 23 24 16 15 18 17 14 13
+ 39 40 37 38 41 42 31 32 33 34 36 35
+ 7 8 9 10 12 11 47 48 44 43 45 46
+ 26 25 29 30 28 27 1 2 6 5 4 3
+ operation j=23 : 23 24 21 22 19 20 29 30 26 25 27 28
+ 38 37 42 41 39 40 8 7 12 11 9 10
+ 2 1 4 3 6 5 18 17 16 15 13 14
+ 47 48 44 43 45 46 31 32 33 34 36 35
+ operation j=24 : 24 23 19 20 21 22 18 17 16 15 13 14
+ 37 38 39 40 42 41 7 8 9 10 12 11
+ 31 32 33 34 36 35 29 30 26 25 27 28
+ 44 43 47 48 46 45 2 1 4 3 6 5
+ operation j=25 : 25 26 30 29 28 27 43 44 45 46 48 47
+ 36 35 32 31 34 33 6 5 1 2 3 4
+ 40 39 41 42 37 38 20 19 23 24 22 21
+ 17 18 14 13 15 16 10 9 11 12 7 8
+ operation j=26 : 26 25 28 27 30 29 20 19 23 24 22 21
+ 35 36 34 33 32 31 5 6 3 4 1 2
+ 10 9 11 12 7 8 43 44 45 46 48 47
+ 14 13 17 18 16 15 40 39 41 42 37 38
+ operation j=27 : 27 28 29 30 26 25 45 46 43 44 47 48
+ 32 31 36 35 33 34 40 39 41 42 37 38
+ 6 5 1 2 3 4 14 13 17 18 16 15
+ 23 24 20 19 21 22 9 10 7 8 11 12
+ operation j=28 : 28 27 26 25 29 30 14 13 17 18 16 15
+ 31 32 33 34 36 35 39 40 37 38 41 42
+ 9 10 7 8 11 12 45 46 43 44 47 48
+ 20 19 23 24 22 21 6 5 1 2 3 4
+ operation j=29 : 29 30 27 28 25 26 23 24 20 19 21 22
+ 34 33 35 36 31 32 10 9 11 12 7 8
+ 5 6 3 4 1 2 17 18 14 13 15 16
+ 45 46 43 44 47 48 39 40 37 38 41 42
+ operation j=30 : 30 29 25 26 27 28 17 18 14 13 15 16
+ 33 34 31 32 35 36 9 10 7 8 11 12
+ 39 40 37 38 41 42 23 24 20 19 21 22
+ 43 44 45 46 48 47 5 6 3 4 1 2
+ operation j=31 : 31 32 35 36 34 33 2 1 4 3 5 6
+ 28 27 30 29 25 26 22 21 24 23 19 20
+ 48 47 46 45 44 43 8 7 12 11 10 9
+ 42 41 38 37 39 40 15 16 13 14 18 17
+ operation j=32 : 32 31 34 33 35 36 8 7 12 11 10 9
+ 27 28 25 26 30 29 21 22 19 20 24 23
+ 15 16 13 14 18 17 2 1 4 3 5 6
+ 38 37 42 41 40 39 48 47 46 45 44 43
+ operation j=33 : 33 34 36 35 32 31 4 3 2 1 6 5
+ 30 29 28 27 26 25 48 47 46 45 44 43
+ 22 21 24 23 19 20 38 37 42 41 40 39
+ 12 11 8 7 9 10 16 15 18 17 13 14
+ operation j=34 : 34 33 32 31 36 35 38 37 42 41 40 39
+ 29 30 26 25 28 27 47 48 44 43 46 45
+ 16 15 18 17 13 14 4 3 2 1 6 5
+ 8 7 12 11 10 9 22 21 24 23 19 20
+ operation j=35 : 35 36 31 32 33 34 42 41 38 37 39 40
+ 26 25 29 30 27 28 16 15 18 17 13 14
+ 47 48 44 43 46 45 12 11 8 7 9 10
+ 2 1 4 3 5 6 21 22 19 20 24 23
+ operation j=36 : 36 35 33 34 31 32 12 11 8 7 9 10
+ 25 26 27 28 29 30 15 16 13 14 18 17
+ 21 22 19 20 24 23 42 41 38 37 39 40
+ 4 3 2 1 6 5 47 48 44 43 46 45
+ operation j=37 : 37 38 41 42 40 39 3 4 5 6 1 2
+ 24 23 22 21 20 19 46 45 48 47 43 44
+ 28 27 30 29 25 26 34 33 35 36 32 31
+ 11 12 10 9 7 8 14 13 17 18 15 16
+ operation j=38 : 38 37 40 39 41 42 34 33 35 36 32 31
+ 23 24 20 19 22 21 45 46 43 44 48 47
+ 14 13 17 18 15 16 3 4 5 6 1 2
+ 10 9 11 12 8 7 28 27 30 29 25 26
+ operation j=39 : 39 40 42 41 38 37 5 6 3 4 2 1
+ 22 21 24 23 19 20 28 27 30 29 25 26
+ 46 45 48 47 43 44 10 9 11 12 8 7
+ 35 36 34 33 31 32 13 14 15 16 17 18
+ operation j=40 : 40 39 38 37 42 41 10 9 11 12 8 7
+ 21 22 19 20 24 23 27 28 25 26 30 29
+ 13 14 15 16 17 18 5 6 3 4 2 1
+ 34 33 35 36 32 31 46 45 48 47 43 44
+ operation j=41 : 41 42 37 38 39 40 11 12 10 9 7 8
+ 19 20 21 22 23 24 13 14 15 16 17 18
+ 27 28 25 26 30 29 35 36 34 33 31 32
+ 3 4 5 6 1 2 45 46 43 44 48 47
+ operation j=42 : 42 41 39 40 37 38 35 36 34 33 31 32
+ 20 19 23 24 21 22 14 13 17 18 15 16
+ 45 46 43 44 48 47 11 12 10 9 7 8
+ 5 6 3 4 2 1 27 28 25 26 30 29
+ operation j=43 : 43 44 48 47 46 45 25 26 27 28 30 29
+ 12 11 8 7 10 9 4 3 2 1 5 6
+ 38 37 42 41 39 40 19 20 21 22 24 23
+ 15 16 13 14 17 18 34 33 35 36 31 32
+ operation j=44 : 44 43 46 45 48 47 19 20 21 22 24 23
+ 11 12 10 9 8 7 3 4 5 6 2 1
+ 34 33 35 36 31 32 25 26 27 28 30 29
+ 13 14 15 16 18 17 38 37 42 41 39 40
+ operation j=45 : 45 46 47 48 44 43 27 28 25 26 29 30
+ 8 7 12 11 9 10 38 37 42 41 39 40
+ 4 3 2 1 5 6 13 14 15 16 18 17
+ 21 22 19 20 23 24 33 34 31 32 35 36
+ operation j=46 : 46 45 44 43 47 48 13 14 15 16 18 17
+ 7 8 9 10 12 11 37 38 39 40 42 41
+ 33 34 31 32 35 36 27 28 25 26 29 30
+ 19 20 21 22 24 23 4 3 2 1 5 6
+ operation j=47 : 47 48 45 46 43 44 21 22 19 20 23 24
+ 10 9 11 12 7 8 34 33 35 36 31 32
+ 3 4 5 6 2 1 15 16 13 14 17 18
+ 27 28 25 26 29 30 37 38 39 40 42 41
+ operation j=48 : 48 47 43 44 45 46 15 16 13 14 17 18
+ 9 10 7 8 11 12 33 34 31 32 35 36
+ 37 38 39 40 42 41 21 22 19 20 23 24
+ 25 26 27 28 30 29 3 4 5 6 2 1
+
+
+ Space group can be generated using 5 generators: 13 4 9 34 2
+
+ generators (in lattice coordinates):
+
+&gen 5
+
+ -1 0 0 0.00000
+ 0 -1 0 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+ 0 -1 1 0.00000
+
+ 0 1 -1 0.00000
+ 1 0 -1 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 1 0.00000
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+
+ -1 0 0 0.00000
+ -1 1 0 0.00000
+ -1 0 1 0.00000
+
+/ ! end generators
+
+
+
+ Atomic positions:
+ -----------------
+ atom types = 1
+ total = 1
+
+ lattice coordinates (scaled) Cartesian coordinates atom
+
+ atom type 1: atomic identification number = 74.0 representative = 1
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1
+
+atoms% 1 atoms 1
+ Z( 1)= 74 atoms 1
+ 0.000000 0.000000 0.000000 1
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+
+ ===============================================
+ === modifying atomic input for &(all)atom ===
+ ===============================================
+
+for atom 1 ( W) changed rmt to 2.100000
+for atom 1 ( W) changed jri to 981
+for atom 1 ( W) changed lmax to 12
+for atom 1 ( W) changed lnonsph to 6
+for atom 1 ( W) set econfig to [Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4
+ corestates = 16 with 60.0 electrons
+ valence st.= 5 with 14.0 electrons
+nlod = 2 llod = 1 : 5s5p
+ nlo( 1) = 2 llo = 0 1
+ lonqn = 5 5
+line: 13>&comp
+line: 14>gmax=15.0 gmaxxc=12.5 kmax=5.0 /
+ ----------
+ core : 1 -1 2.0
+ core : 2 -1 2.0
+ core : 2 1 2.0
+ core : 2 -2 4.0
+ core : 3 -1 2.0
+ core : 3 1 2.0
+ core : 3 -2 4.0
+ core : 3 2 4.0
+ core : 3 -3 6.0
+ core : 4 -1 2.0
+ core : 4 1 2.0
+ core : 4 -2 4.0
+ core : 4 2 4.0
+ core : 4 -3 6.0
+ core : 4 3 6.0
+ core : 4 -4 8.0
+ valence : 5 -1 2.0 5s
+ valence : 5 1 2.0 5p
+ valence : 5 -2 4.0 5p
+ valence : 6 -1 2.0 6s
+ valence : 5 2 2.0 5d
+ valence : 5 -3 2.0 5d
+ ----------
+Valence Electrons = 14
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+line: 15>&kpt
+line: 16>div1=3 div2=3 div3=3 tkb=0.0005 /
+ 5.22007561238382 5.22007561238382 5.22007561238382
+ -0.333333333333333 -0.333333333333333 -0.333333333333333
+ body centered cubic
+ values accepted unchanged
+ 3 3 3 nmop(i),i=1,3
+ orientation of boundary faces
+ 1 -1 -0.5740361 ifac,iside,orient for xvec
+ 2 -1 -0.0454288 ifac,iside,orient for xvec
+ 3 -1 -0.0256305 ifac,iside,orient for xvec
+ 4 -1 -0.0469244 ifac,iside,orient for xvec
+Bravais lattice vectors
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+reciprocal lattice vectors
+ 0.000000 1.042398 1.042398
+ 1.042398 0.000000 1.042398
+ 1.042398 1.042398 0.000000
+ 3 3 3 Monkhorst-Pack-parameters
+ 0 nreg; k-points in irreducible wedge of BZ
+ Monkhorst-Pack-fractions
+ 0 nbound; no k-points on boundary of BZ
+ 1 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 2 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 3 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+
+k-point count: 4
+
+k-point mesh: 3 3 3
+k-point density: 2.035038 2.035038 2.035038
+
diff --git a/tests/parsers/fixtures/inpgen/broken_inpxml/out.error b/tests/parsers/fixtures/inpgen/broken_inpxml/out.error
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/fixtures/inpgen/default/inp.xml b/tests/parsers/fixtures/inpgen/default/inp.xml
new file mode 100644
index 000000000..2bf34f24c
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/default/inp.xml
@@ -0,0 +1,319 @@
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ -0.000000 0.333333 0.333333
+ -0.333333 0.333333 0.333333
+ -0.000000 0.000000 0.333333
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+
+
+
+
+ -3.013812060000000 3.013812060000000 3.013812060000000
+ 3.013812060000000 -3.013812060000000 3.013812060000000
+ 3.013812060000000 3.013812060000000 -3.013812060000000
+
+
+ |
+
+
+
+
+
+
+
+
+ [Kr] (4d3/2) (4d5/2) (4f5/2) (4f7/2)
+ (5s1/2) (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/inpgen/default/out b/tests/parsers/fixtures/inpgen/default/out
new file mode 100644
index 000000000..fca99897b
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/default/out
@@ -0,0 +1,687 @@
+line: 1>A Fleur input generator calculation with aiida
+line: 2>&input cartesian=F /
+line: 3>-3.0138120600 3.0138120600 3.0138120600
+line: 4>3.0138120600 -3.0138120600 3.0138120600
+line: 5>3.0138120600 3.0138120600 -3.0138120600
+line: 6>1.0000000000
+line: 7>1.0000000000 1.0000000000 1.0000000000
+line: 8>
+line: 9>1
+line: 10>74 0.0000000000 0.0000000000 0.0000000000
+line: 11>&atom
+line: 12>econfig="[Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4" element="W" jri=981 lm
+
+ A Fleur input generator calculation with aiida
+
+ film= F cartesian= F
+ checkinp= F symor= F
+
+a1 = -3.01381 3.01381 3.01381
+a2 = 3.01381 -3.01381 3.01381
+a3 = 3.01381 3.01381 -3.01381
+
+dvac= -3.01381 aa = 1.00000
+scale = 1.00000 1.00000 1.00000
+
+natin= 1 Z = 74
+ positions:
+ 0.00000 0.00000 0.00000
+
+ generators: 0 (excluding identity)
+
+
+ Lattice information:
+ --------------------
+
+ overall lattice constant a0 = 1.000000 bohr
+
+ real-space primitive lattice vectors in units of a_{x,y,z}
+ a_1: -3.013812 3.013812 3.013812
+ a_2: 3.013812 -3.013812 3.013812
+ a_3: 3.013812 3.013812 -3.013812
+
+ lattice constants a_x, a_y, a_z = 1.000000 1.000000 1.000000
+ volume of unit cell (a.u.^3) = 109.498581
+
+dbg: lattice matrices
+ 109.498580847925
+dbg: as :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bs :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: amat :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bmat :
+ 0.000000 0.521199 0.521199
+ 0.521199 0.000000 0.521199
+ 0.521199 0.521199 0.000000
+dbg: amatinv :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: aamat :
+ 27.249189 -9.083063 -9.083063
+ -9.083063 27.249189 -9.083063
+ -9.083063 -9.083063 27.249189
+dbg: bbmat :
+ 0.543297 0.271649 0.271649
+ 0.271649 0.543297 0.271649
+ 0.271649 0.271649 0.543297
+
+dbg: lattice vectors :
+vector 1 : -3.01381 3.01381 3.01381 length : 5.22008
+vector 2 : 3.01381 -3.01381 3.01381 length : 5.22008
+vector 3 : 3.01381 3.01381 -3.01381 length : 5.22008
+angle between vectors (1,2) =109.47122
+angle between vectors (1,3) =109.47122
+angle between vectors (2,3) =109.47122
+
+dbg: reciprocal lattice vectors :
+vector 1 : 0.00000 0.52120 0.52120 length : 0.73709
+vector 2 : 0.52120 0.00000 0.52120 length : 0.73709
+vector 3 : 0.52120 0.52120 0.00000 length : 0.73709
+angle between vectors (1,2) = 60.00000
+angle between vectors (1,3) = 60.00000
+angle between vectors (2,3) = 60.00000
+
+
+ Point group of the Bravais lattice has 48 operations
+
+ DBG: symor,zorth,oldfleur : T F F
+ DBG: optype : 1 -2 -2 3 3 -2 -2 3 2 -4 3 -4 -1 2 2 -3 -3 2 2 -2 -3 4 4 -3 -3 4 2 -3 -2 4 3 -2 -4 2 -4 3 3 -4 -4 3 -2 2 4 -3 -3 2 4 -2
+ DBG: invsym,invs,zrfs,invs2 : T T F F
+ DBG: (before reorder) invsop,zrfsop,invs2op : 13 7 46
+
+ Space group information:
+ ------------------------
+ 48 operations
+ space group is symmorphic
+ has inversion symmetry
+
+
+ Operations: (in International notation)
+ ---------------------------------------
+ lattice coordinates (scaled) Cartesian coordinates
+
+ operation 1: 1 (inverse = 1)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 2: 2 (inverse = 2)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 3: 2 (inverse = 3)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 4: 3 (inverse = 5)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 5: 3 (inverse = 4)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 6: 2 (inverse = 6)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 7: 2 (inverse = 7)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 8: 3 (inverse = 31)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 9: 2 (inverse = 9)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 10: 4 (inverse = 33)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 11: 3 (inverse = 37)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 12: 4 (inverse = 39)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 13: 1 (inverse = 13)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 14: 2 (inverse = 14)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 15: 2 (inverse = 15)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 16: 3 (inverse = 17)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 17: 3 (inverse = 16)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 18: 2 (inverse = 18)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 19: 2 (inverse = 19)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 20: 2 (inverse = 20)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 21: 3 (inverse = 25)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 22: 4 (inverse = 43)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+
+ operation 23: 4 (inverse = 26)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 24: 3 (inverse = 44)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 25: 3 (inverse = 21)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+
+ operation 26: 4 (inverse = 23)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+
+ operation 27: 2 (inverse = 27)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 28: 3 (inverse = 45)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 29: 2 (inverse = 29)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 30: 4 (inverse = 47)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 31: 3 (inverse = 8)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 32: 2 (inverse = 32)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 33: 4 (inverse = 10)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 34: 2 (inverse = 34)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 35: 4 (inverse = 38)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 36: 3 (inverse = 40)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 37: 3 (inverse = 11)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 38: 4 (inverse = 35)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 39: 4 (inverse = 12)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 40: 3 (inverse = 36)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 41: 2 (inverse = 41)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 42: 2 (inverse = 42)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 43: 4 (inverse = 22)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 44: 3 (inverse = 24)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 45: 3 (inverse = 28)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 46: 2 (inverse = 46)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ operation 47: 4 (inverse = 30)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 48: 2 (inverse = 48)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ Multiplcation table: {R_j|t_j}{R_i|t_i}
+ operation j= 1 : 1 2 3 4 5 6 7 8 9 10 11 12
+ 13 14 15 16 17 18 19 20 21 22 23 24
+ 25 26 27 28 29 30 31 32 33 34 35 36
+ 37 38 39 40 41 42 43 44 45 46 47 48
+ operation j= 2 : 2 1 5 6 3 4 31 32 33 34 35 36
+ 14 13 17 18 15 16 20 19 23 24 21 22
+ 43 44 45 46 47 48 7 8 9 10 11 12
+ 39 40 37 38 42 41 25 26 27 28 29 30
+ operation j= 3 : 3 4 1 2 6 5 37 38 39 40 41 42
+ 18 17 16 15 14 13 44 43 47 48 45 46
+ 26 25 29 30 27 28 33 34 31 32 36 35
+ 7 8 9 10 11 12 20 19 23 24 21 22
+ operation j= 4 : 4 3 6 5 1 2 33 34 31 32 36 35
+ 17 18 14 13 16 15 43 44 45 46 47 48
+ 20 19 23 24 21 22 37 38 39 40 41 42
+ 9 10 7 8 12 11 26 25 29 30 27 28
+ operation j= 5 : 5 6 2 1 4 3 39 40 37 38 42 41
+ 16 15 18 17 13 14 26 25 29 30 27 28
+ 44 43 47 48 45 46 9 10 7 8 12 11
+ 31 32 33 34 35 36 19 20 21 22 23 24
+ operation j= 6 : 6 5 4 3 2 1 9 10 7 8 12 11
+ 15 16 13 14 18 17 25 26 27 28 29 30
+ 19 20 21 22 23 24 39 40 37 38 42 41
+ 33 34 31 32 36 35 44 43 47 48 45 46
+ operation j= 7 : 7 8 11 12 10 9 1 2 6 5 3 4
+ 46 45 48 47 43 44 24 23 22 21 20 19
+ 30 29 28 27 26 25 32 31 36 35 34 33
+ 41 42 40 39 37 38 17 18 14 13 16 15
+ operation j= 8 : 8 7 10 9 11 12 32 31 36 35 34 33
+ 45 46 43 44 48 47 23 24 20 19 22 21
+ 17 18 14 13 16 15 1 2 6 5 3 4
+ 40 39 41 42 38 37 30 29 28 27 26 25
+ operation j= 9 : 9 10 12 11 8 7 6 5 1 2 4 3
+ 48 47 46 45 44 43 30 29 28 27 26 25
+ 24 23 22 21 20 19 40 39 41 42 38 37
+ 36 35 32 31 33 34 18 17 16 15 14 13
+ operation j=10 : 10 9 8 7 12 11 40 39 41 42 38 37
+ 47 48 44 43 46 45 29 30 26 25 28 27
+ 18 17 16 15 14 13 6 5 1 2 4 3
+ 32 31 36 35 34 33 24 23 22 21 20 19
+ operation j=11 : 11 12 7 8 9 10 41 42 40 39 37 38
+ 44 43 47 48 45 46 18 17 16 15 14 13
+ 29 30 26 25 28 27 36 35 32 31 33 34
+ 1 2 6 5 3 4 23 24 20 19 22 21
+ operation j=12 : 12 11 9 10 7 8 36 35 32 31 33 34
+ 43 44 45 46 47 48 17 18 14 13 16 15
+ 23 24 20 19 22 21 41 42 40 39 37 38
+ 6 5 1 2 4 3 29 30 26 25 28 27
+ operation j=13 : 13 14 18 17 16 15 46 45 48 47 44 43
+ 1 2 6 5 4 3 41 42 40 39 38 37
+ 36 35 32 31 34 33 28 27 30 29 26 25
+ 24 23 22 21 19 20 12 11 8 7 10 9
+ operation j=14 : 14 13 16 15 18 17 28 27 30 29 26 25
+ 2 1 4 3 6 5 42 41 38 37 40 39
+ 12 11 8 7 10 9 46 45 48 47 44 43
+ 22 21 24 23 20 19 36 35 32 31 34 33
+ operation j=15 : 15 16 17 18 14 13 48 47 46 45 43 44
+ 6 5 1 2 3 4 36 35 32 31 34 33
+ 41 42 40 39 38 37 22 21 24 23 20 19
+ 30 29 28 27 25 26 11 12 10 9 8 7
+ operation j=16 : 16 15 14 13 17 18 22 21 24 23 20 19
+ 5 6 3 4 1 2 35 36 34 33 32 31
+ 11 12 10 9 8 7 48 47 46 45 43 44
+ 28 27 30 29 26 25 41 42 40 39 38 37
+ operation j=17 : 17 18 15 16 13 14 30 29 28 27 25 26
+ 4 3 2 1 5 6 12 11 8 7 10 9
+ 42 41 38 37 40 39 24 23 22 21 19 20
+ 48 47 46 45 43 44 35 36 34 33 32 31
+ operation j=18 : 18 17 13 14 15 16 24 23 22 21 19 20
+ 3 4 5 6 2 1 11 12 10 9 8 7
+ 35 36 34 33 32 31 30 29 28 27 25 26
+ 46 45 48 47 44 43 42 41 38 37 40 39
+ operation j=19 : 19 20 24 23 22 21 44 43 47 48 46 45
+ 41 42 40 39 38 37 1 2 6 5 4 3
+ 32 31 36 35 33 34 26 25 29 30 28 27
+ 18 17 16 15 13 14 8 7 12 11 9 10
+ operation j=20 : 20 19 22 21 24 23 26 25 29 30 28 27
+ 42 41 38 37 40 39 2 1 4 3 6 5
+ 8 7 12 11 9 10 44 43 47 48 46 45
+ 16 15 18 17 14 13 32 31 36 35 33 34
+ operation j=21 : 21 22 23 24 20 19 47 48 44 43 45 46
+ 40 39 41 42 37 38 32 31 36 35 33 34
+ 1 2 6 5 4 3 16 15 18 17 14 13
+ 29 30 26 25 27 28 7 8 9 10 12 11
+ operation j=22 : 22 21 20 19 23 24 16 15 18 17 14 13
+ 39 40 37 38 41 42 31 32 33 34 36 35
+ 7 8 9 10 12 11 47 48 44 43 45 46
+ 26 25 29 30 28 27 1 2 6 5 4 3
+ operation j=23 : 23 24 21 22 19 20 29 30 26 25 27 28
+ 38 37 42 41 39 40 8 7 12 11 9 10
+ 2 1 4 3 6 5 18 17 16 15 13 14
+ 47 48 44 43 45 46 31 32 33 34 36 35
+ operation j=24 : 24 23 19 20 21 22 18 17 16 15 13 14
+ 37 38 39 40 42 41 7 8 9 10 12 11
+ 31 32 33 34 36 35 29 30 26 25 27 28
+ 44 43 47 48 46 45 2 1 4 3 6 5
+ operation j=25 : 25 26 30 29 28 27 43 44 45 46 48 47
+ 36 35 32 31 34 33 6 5 1 2 3 4
+ 40 39 41 42 37 38 20 19 23 24 22 21
+ 17 18 14 13 15 16 10 9 11 12 7 8
+ operation j=26 : 26 25 28 27 30 29 20 19 23 24 22 21
+ 35 36 34 33 32 31 5 6 3 4 1 2
+ 10 9 11 12 7 8 43 44 45 46 48 47
+ 14 13 17 18 16 15 40 39 41 42 37 38
+ operation j=27 : 27 28 29 30 26 25 45 46 43 44 47 48
+ 32 31 36 35 33 34 40 39 41 42 37 38
+ 6 5 1 2 3 4 14 13 17 18 16 15
+ 23 24 20 19 21 22 9 10 7 8 11 12
+ operation j=28 : 28 27 26 25 29 30 14 13 17 18 16 15
+ 31 32 33 34 36 35 39 40 37 38 41 42
+ 9 10 7 8 11 12 45 46 43 44 47 48
+ 20 19 23 24 22 21 6 5 1 2 3 4
+ operation j=29 : 29 30 27 28 25 26 23 24 20 19 21 22
+ 34 33 35 36 31 32 10 9 11 12 7 8
+ 5 6 3 4 1 2 17 18 14 13 15 16
+ 45 46 43 44 47 48 39 40 37 38 41 42
+ operation j=30 : 30 29 25 26 27 28 17 18 14 13 15 16
+ 33 34 31 32 35 36 9 10 7 8 11 12
+ 39 40 37 38 41 42 23 24 20 19 21 22
+ 43 44 45 46 48 47 5 6 3 4 1 2
+ operation j=31 : 31 32 35 36 34 33 2 1 4 3 5 6
+ 28 27 30 29 25 26 22 21 24 23 19 20
+ 48 47 46 45 44 43 8 7 12 11 10 9
+ 42 41 38 37 39 40 15 16 13 14 18 17
+ operation j=32 : 32 31 34 33 35 36 8 7 12 11 10 9
+ 27 28 25 26 30 29 21 22 19 20 24 23
+ 15 16 13 14 18 17 2 1 4 3 5 6
+ 38 37 42 41 40 39 48 47 46 45 44 43
+ operation j=33 : 33 34 36 35 32 31 4 3 2 1 6 5
+ 30 29 28 27 26 25 48 47 46 45 44 43
+ 22 21 24 23 19 20 38 37 42 41 40 39
+ 12 11 8 7 9 10 16 15 18 17 13 14
+ operation j=34 : 34 33 32 31 36 35 38 37 42 41 40 39
+ 29 30 26 25 28 27 47 48 44 43 46 45
+ 16 15 18 17 13 14 4 3 2 1 6 5
+ 8 7 12 11 10 9 22 21 24 23 19 20
+ operation j=35 : 35 36 31 32 33 34 42 41 38 37 39 40
+ 26 25 29 30 27 28 16 15 18 17 13 14
+ 47 48 44 43 46 45 12 11 8 7 9 10
+ 2 1 4 3 5 6 21 22 19 20 24 23
+ operation j=36 : 36 35 33 34 31 32 12 11 8 7 9 10
+ 25 26 27 28 29 30 15 16 13 14 18 17
+ 21 22 19 20 24 23 42 41 38 37 39 40
+ 4 3 2 1 6 5 47 48 44 43 46 45
+ operation j=37 : 37 38 41 42 40 39 3 4 5 6 1 2
+ 24 23 22 21 20 19 46 45 48 47 43 44
+ 28 27 30 29 25 26 34 33 35 36 32 31
+ 11 12 10 9 7 8 14 13 17 18 15 16
+ operation j=38 : 38 37 40 39 41 42 34 33 35 36 32 31
+ 23 24 20 19 22 21 45 46 43 44 48 47
+ 14 13 17 18 15 16 3 4 5 6 1 2
+ 10 9 11 12 8 7 28 27 30 29 25 26
+ operation j=39 : 39 40 42 41 38 37 5 6 3 4 2 1
+ 22 21 24 23 19 20 28 27 30 29 25 26
+ 46 45 48 47 43 44 10 9 11 12 8 7
+ 35 36 34 33 31 32 13 14 15 16 17 18
+ operation j=40 : 40 39 38 37 42 41 10 9 11 12 8 7
+ 21 22 19 20 24 23 27 28 25 26 30 29
+ 13 14 15 16 17 18 5 6 3 4 2 1
+ 34 33 35 36 32 31 46 45 48 47 43 44
+ operation j=41 : 41 42 37 38 39 40 11 12 10 9 7 8
+ 19 20 21 22 23 24 13 14 15 16 17 18
+ 27 28 25 26 30 29 35 36 34 33 31 32
+ 3 4 5 6 1 2 45 46 43 44 48 47
+ operation j=42 : 42 41 39 40 37 38 35 36 34 33 31 32
+ 20 19 23 24 21 22 14 13 17 18 15 16
+ 45 46 43 44 48 47 11 12 10 9 7 8
+ 5 6 3 4 2 1 27 28 25 26 30 29
+ operation j=43 : 43 44 48 47 46 45 25 26 27 28 30 29
+ 12 11 8 7 10 9 4 3 2 1 5 6
+ 38 37 42 41 39 40 19 20 21 22 24 23
+ 15 16 13 14 17 18 34 33 35 36 31 32
+ operation j=44 : 44 43 46 45 48 47 19 20 21 22 24 23
+ 11 12 10 9 8 7 3 4 5 6 2 1
+ 34 33 35 36 31 32 25 26 27 28 30 29
+ 13 14 15 16 18 17 38 37 42 41 39 40
+ operation j=45 : 45 46 47 48 44 43 27 28 25 26 29 30
+ 8 7 12 11 9 10 38 37 42 41 39 40
+ 4 3 2 1 5 6 13 14 15 16 18 17
+ 21 22 19 20 23 24 33 34 31 32 35 36
+ operation j=46 : 46 45 44 43 47 48 13 14 15 16 18 17
+ 7 8 9 10 12 11 37 38 39 40 42 41
+ 33 34 31 32 35 36 27 28 25 26 29 30
+ 19 20 21 22 24 23 4 3 2 1 5 6
+ operation j=47 : 47 48 45 46 43 44 21 22 19 20 23 24
+ 10 9 11 12 7 8 34 33 35 36 31 32
+ 3 4 5 6 2 1 15 16 13 14 17 18
+ 27 28 25 26 29 30 37 38 39 40 42 41
+ operation j=48 : 48 47 43 44 45 46 15 16 13 14 17 18
+ 9 10 7 8 11 12 33 34 31 32 35 36
+ 37 38 39 40 42 41 21 22 19 20 23 24
+ 25 26 27 28 30 29 3 4 5 6 2 1
+
+
+ Space group can be generated using 5 generators: 13 4 9 34 2
+
+ generators (in lattice coordinates):
+
+&gen 5
+
+ -1 0 0 0.00000
+ 0 -1 0 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+ 0 -1 1 0.00000
+
+ 0 1 -1 0.00000
+ 1 0 -1 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 1 0.00000
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+
+ -1 0 0 0.00000
+ -1 1 0 0.00000
+ -1 0 1 0.00000
+
+/ ! end generators
+
+
+
+ Atomic positions:
+ -----------------
+ atom types = 1
+ total = 1
+
+ lattice coordinates (scaled) Cartesian coordinates atom
+
+ atom type 1: atomic identification number = 74.0 representative = 1
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1
+
+atoms% 1 atoms 1
+ Z( 1)= 74 atoms 1
+ 0.000000 0.000000 0.000000 1
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+
+ ===============================================
+ === modifying atomic input for &(all)atom ===
+ ===============================================
+
+for atom 1 ( W) changed rmt to 2.100000
+for atom 1 ( W) changed jri to 981
+for atom 1 ( W) changed lmax to 12
+for atom 1 ( W) changed lnonsph to 6
+for atom 1 ( W) set econfig to [Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4
+ corestates = 16 with 60.0 electrons
+ valence st.= 5 with 14.0 electrons
+nlod = 2 llod = 1 : 5s5p
+ nlo( 1) = 2 llo = 0 1
+ lonqn = 5 5
+line: 13>&comp
+line: 14>gmax=15.0 gmaxxc=12.5 kmax=5.0 /
+ ----------
+ core : 1 -1 2.0
+ core : 2 -1 2.0
+ core : 2 1 2.0
+ core : 2 -2 4.0
+ core : 3 -1 2.0
+ core : 3 1 2.0
+ core : 3 -2 4.0
+ core : 3 2 4.0
+ core : 3 -3 6.0
+ core : 4 -1 2.0
+ core : 4 1 2.0
+ core : 4 -2 4.0
+ core : 4 2 4.0
+ core : 4 -3 6.0
+ core : 4 3 6.0
+ core : 4 -4 8.0
+ valence : 5 -1 2.0 5s
+ valence : 5 1 2.0 5p
+ valence : 5 -2 4.0 5p
+ valence : 6 -1 2.0 6s
+ valence : 5 2 2.0 5d
+ valence : 5 -3 2.0 5d
+ ----------
+Valence Electrons = 14
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+line: 15>&kpt
+line: 16>div1=3 div2=3 div3=3 tkb=0.0005 /
+ 5.22007561238382 5.22007561238382 5.22007561238382
+ -0.333333333333333 -0.333333333333333 -0.333333333333333
+ body centered cubic
+ values accepted unchanged
+ 3 3 3 nmop(i),i=1,3
+ orientation of boundary faces
+ 1 -1 -0.5740361 ifac,iside,orient for xvec
+ 2 -1 -0.0454288 ifac,iside,orient for xvec
+ 3 -1 -0.0256305 ifac,iside,orient for xvec
+ 4 -1 -0.0469244 ifac,iside,orient for xvec
+Bravais lattice vectors
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+reciprocal lattice vectors
+ 0.000000 1.042398 1.042398
+ 1.042398 0.000000 1.042398
+ 1.042398 1.042398 0.000000
+ 3 3 3 Monkhorst-Pack-parameters
+ 0 nreg; k-points in irreducible wedge of BZ
+ Monkhorst-Pack-fractions
+ 0 nbound; no k-points on boundary of BZ
+ 1 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 2 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 3 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+
+k-point count: 4
+
+k-point mesh: 3 3 3
+k-point density: 2.035038 2.035038 2.035038
+
diff --git a/tests/parsers/fixtures/inpgen/default/out.error b/tests/parsers/fixtures/inpgen/default/out.error
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/fixtures/inpgen/no_inpxml/out b/tests/parsers/fixtures/inpgen/no_inpxml/out
new file mode 100644
index 000000000..fca99897b
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/no_inpxml/out
@@ -0,0 +1,687 @@
+line: 1>A Fleur input generator calculation with aiida
+line: 2>&input cartesian=F /
+line: 3>-3.0138120600 3.0138120600 3.0138120600
+line: 4>3.0138120600 -3.0138120600 3.0138120600
+line: 5>3.0138120600 3.0138120600 -3.0138120600
+line: 6>1.0000000000
+line: 7>1.0000000000 1.0000000000 1.0000000000
+line: 8>
+line: 9>1
+line: 10>74 0.0000000000 0.0000000000 0.0000000000
+line: 11>&atom
+line: 12>econfig="[Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4" element="W" jri=981 lm
+
+ A Fleur input generator calculation with aiida
+
+ film= F cartesian= F
+ checkinp= F symor= F
+
+a1 = -3.01381 3.01381 3.01381
+a2 = 3.01381 -3.01381 3.01381
+a3 = 3.01381 3.01381 -3.01381
+
+dvac= -3.01381 aa = 1.00000
+scale = 1.00000 1.00000 1.00000
+
+natin= 1 Z = 74
+ positions:
+ 0.00000 0.00000 0.00000
+
+ generators: 0 (excluding identity)
+
+
+ Lattice information:
+ --------------------
+
+ overall lattice constant a0 = 1.000000 bohr
+
+ real-space primitive lattice vectors in units of a_{x,y,z}
+ a_1: -3.013812 3.013812 3.013812
+ a_2: 3.013812 -3.013812 3.013812
+ a_3: 3.013812 3.013812 -3.013812
+
+ lattice constants a_x, a_y, a_z = 1.000000 1.000000 1.000000
+ volume of unit cell (a.u.^3) = 109.498581
+
+dbg: lattice matrices
+ 109.498580847925
+dbg: as :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bs :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: amat :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bmat :
+ 0.000000 0.521199 0.521199
+ 0.521199 0.000000 0.521199
+ 0.521199 0.521199 0.000000
+dbg: amatinv :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: aamat :
+ 27.249189 -9.083063 -9.083063
+ -9.083063 27.249189 -9.083063
+ -9.083063 -9.083063 27.249189
+dbg: bbmat :
+ 0.543297 0.271649 0.271649
+ 0.271649 0.543297 0.271649
+ 0.271649 0.271649 0.543297
+
+dbg: lattice vectors :
+vector 1 : -3.01381 3.01381 3.01381 length : 5.22008
+vector 2 : 3.01381 -3.01381 3.01381 length : 5.22008
+vector 3 : 3.01381 3.01381 -3.01381 length : 5.22008
+angle between vectors (1,2) =109.47122
+angle between vectors (1,3) =109.47122
+angle between vectors (2,3) =109.47122
+
+dbg: reciprocal lattice vectors :
+vector 1 : 0.00000 0.52120 0.52120 length : 0.73709
+vector 2 : 0.52120 0.00000 0.52120 length : 0.73709
+vector 3 : 0.52120 0.52120 0.00000 length : 0.73709
+angle between vectors (1,2) = 60.00000
+angle between vectors (1,3) = 60.00000
+angle between vectors (2,3) = 60.00000
+
+
+ Point group of the Bravais lattice has 48 operations
+
+ DBG: symor,zorth,oldfleur : T F F
+ DBG: optype : 1 -2 -2 3 3 -2 -2 3 2 -4 3 -4 -1 2 2 -3 -3 2 2 -2 -3 4 4 -3 -3 4 2 -3 -2 4 3 -2 -4 2 -4 3 3 -4 -4 3 -2 2 4 -3 -3 2 4 -2
+ DBG: invsym,invs,zrfs,invs2 : T T F F
+ DBG: (before reorder) invsop,zrfsop,invs2op : 13 7 46
+
+ Space group information:
+ ------------------------
+ 48 operations
+ space group is symmorphic
+ has inversion symmetry
+
+
+ Operations: (in International notation)
+ ---------------------------------------
+ lattice coordinates (scaled) Cartesian coordinates
+
+ operation 1: 1 (inverse = 1)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 2: 2 (inverse = 2)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 3: 2 (inverse = 3)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 4: 3 (inverse = 5)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 5: 3 (inverse = 4)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 6: 2 (inverse = 6)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 7: 2 (inverse = 7)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 8: 3 (inverse = 31)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 9: 2 (inverse = 9)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 10: 4 (inverse = 33)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 11: 3 (inverse = 37)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 12: 4 (inverse = 39)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 13: 1 (inverse = 13)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 14: 2 (inverse = 14)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 15: 2 (inverse = 15)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 16: 3 (inverse = 17)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 17: 3 (inverse = 16)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 18: 2 (inverse = 18)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 19: 2 (inverse = 19)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 20: 2 (inverse = 20)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 21: 3 (inverse = 25)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 22: 4 (inverse = 43)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+
+ operation 23: 4 (inverse = 26)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 24: 3 (inverse = 44)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 25: 3 (inverse = 21)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+
+ operation 26: 4 (inverse = 23)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+
+ operation 27: 2 (inverse = 27)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 28: 3 (inverse = 45)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 29: 2 (inverse = 29)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 30: 4 (inverse = 47)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 31: 3 (inverse = 8)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 32: 2 (inverse = 32)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 33: 4 (inverse = 10)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 34: 2 (inverse = 34)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 35: 4 (inverse = 38)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 36: 3 (inverse = 40)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 37: 3 (inverse = 11)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 38: 4 (inverse = 35)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 39: 4 (inverse = 12)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 40: 3 (inverse = 36)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 41: 2 (inverse = 41)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 42: 2 (inverse = 42)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 43: 4 (inverse = 22)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 44: 3 (inverse = 24)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 45: 3 (inverse = 28)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 46: 2 (inverse = 46)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ operation 47: 4 (inverse = 30)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 48: 2 (inverse = 48)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ Multiplcation table: {R_j|t_j}{R_i|t_i}
+ operation j= 1 : 1 2 3 4 5 6 7 8 9 10 11 12
+ 13 14 15 16 17 18 19 20 21 22 23 24
+ 25 26 27 28 29 30 31 32 33 34 35 36
+ 37 38 39 40 41 42 43 44 45 46 47 48
+ operation j= 2 : 2 1 5 6 3 4 31 32 33 34 35 36
+ 14 13 17 18 15 16 20 19 23 24 21 22
+ 43 44 45 46 47 48 7 8 9 10 11 12
+ 39 40 37 38 42 41 25 26 27 28 29 30
+ operation j= 3 : 3 4 1 2 6 5 37 38 39 40 41 42
+ 18 17 16 15 14 13 44 43 47 48 45 46
+ 26 25 29 30 27 28 33 34 31 32 36 35
+ 7 8 9 10 11 12 20 19 23 24 21 22
+ operation j= 4 : 4 3 6 5 1 2 33 34 31 32 36 35
+ 17 18 14 13 16 15 43 44 45 46 47 48
+ 20 19 23 24 21 22 37 38 39 40 41 42
+ 9 10 7 8 12 11 26 25 29 30 27 28
+ operation j= 5 : 5 6 2 1 4 3 39 40 37 38 42 41
+ 16 15 18 17 13 14 26 25 29 30 27 28
+ 44 43 47 48 45 46 9 10 7 8 12 11
+ 31 32 33 34 35 36 19 20 21 22 23 24
+ operation j= 6 : 6 5 4 3 2 1 9 10 7 8 12 11
+ 15 16 13 14 18 17 25 26 27 28 29 30
+ 19 20 21 22 23 24 39 40 37 38 42 41
+ 33 34 31 32 36 35 44 43 47 48 45 46
+ operation j= 7 : 7 8 11 12 10 9 1 2 6 5 3 4
+ 46 45 48 47 43 44 24 23 22 21 20 19
+ 30 29 28 27 26 25 32 31 36 35 34 33
+ 41 42 40 39 37 38 17 18 14 13 16 15
+ operation j= 8 : 8 7 10 9 11 12 32 31 36 35 34 33
+ 45 46 43 44 48 47 23 24 20 19 22 21
+ 17 18 14 13 16 15 1 2 6 5 3 4
+ 40 39 41 42 38 37 30 29 28 27 26 25
+ operation j= 9 : 9 10 12 11 8 7 6 5 1 2 4 3
+ 48 47 46 45 44 43 30 29 28 27 26 25
+ 24 23 22 21 20 19 40 39 41 42 38 37
+ 36 35 32 31 33 34 18 17 16 15 14 13
+ operation j=10 : 10 9 8 7 12 11 40 39 41 42 38 37
+ 47 48 44 43 46 45 29 30 26 25 28 27
+ 18 17 16 15 14 13 6 5 1 2 4 3
+ 32 31 36 35 34 33 24 23 22 21 20 19
+ operation j=11 : 11 12 7 8 9 10 41 42 40 39 37 38
+ 44 43 47 48 45 46 18 17 16 15 14 13
+ 29 30 26 25 28 27 36 35 32 31 33 34
+ 1 2 6 5 3 4 23 24 20 19 22 21
+ operation j=12 : 12 11 9 10 7 8 36 35 32 31 33 34
+ 43 44 45 46 47 48 17 18 14 13 16 15
+ 23 24 20 19 22 21 41 42 40 39 37 38
+ 6 5 1 2 4 3 29 30 26 25 28 27
+ operation j=13 : 13 14 18 17 16 15 46 45 48 47 44 43
+ 1 2 6 5 4 3 41 42 40 39 38 37
+ 36 35 32 31 34 33 28 27 30 29 26 25
+ 24 23 22 21 19 20 12 11 8 7 10 9
+ operation j=14 : 14 13 16 15 18 17 28 27 30 29 26 25
+ 2 1 4 3 6 5 42 41 38 37 40 39
+ 12 11 8 7 10 9 46 45 48 47 44 43
+ 22 21 24 23 20 19 36 35 32 31 34 33
+ operation j=15 : 15 16 17 18 14 13 48 47 46 45 43 44
+ 6 5 1 2 3 4 36 35 32 31 34 33
+ 41 42 40 39 38 37 22 21 24 23 20 19
+ 30 29 28 27 25 26 11 12 10 9 8 7
+ operation j=16 : 16 15 14 13 17 18 22 21 24 23 20 19
+ 5 6 3 4 1 2 35 36 34 33 32 31
+ 11 12 10 9 8 7 48 47 46 45 43 44
+ 28 27 30 29 26 25 41 42 40 39 38 37
+ operation j=17 : 17 18 15 16 13 14 30 29 28 27 25 26
+ 4 3 2 1 5 6 12 11 8 7 10 9
+ 42 41 38 37 40 39 24 23 22 21 19 20
+ 48 47 46 45 43 44 35 36 34 33 32 31
+ operation j=18 : 18 17 13 14 15 16 24 23 22 21 19 20
+ 3 4 5 6 2 1 11 12 10 9 8 7
+ 35 36 34 33 32 31 30 29 28 27 25 26
+ 46 45 48 47 44 43 42 41 38 37 40 39
+ operation j=19 : 19 20 24 23 22 21 44 43 47 48 46 45
+ 41 42 40 39 38 37 1 2 6 5 4 3
+ 32 31 36 35 33 34 26 25 29 30 28 27
+ 18 17 16 15 13 14 8 7 12 11 9 10
+ operation j=20 : 20 19 22 21 24 23 26 25 29 30 28 27
+ 42 41 38 37 40 39 2 1 4 3 6 5
+ 8 7 12 11 9 10 44 43 47 48 46 45
+ 16 15 18 17 14 13 32 31 36 35 33 34
+ operation j=21 : 21 22 23 24 20 19 47 48 44 43 45 46
+ 40 39 41 42 37 38 32 31 36 35 33 34
+ 1 2 6 5 4 3 16 15 18 17 14 13
+ 29 30 26 25 27 28 7 8 9 10 12 11
+ operation j=22 : 22 21 20 19 23 24 16 15 18 17 14 13
+ 39 40 37 38 41 42 31 32 33 34 36 35
+ 7 8 9 10 12 11 47 48 44 43 45 46
+ 26 25 29 30 28 27 1 2 6 5 4 3
+ operation j=23 : 23 24 21 22 19 20 29 30 26 25 27 28
+ 38 37 42 41 39 40 8 7 12 11 9 10
+ 2 1 4 3 6 5 18 17 16 15 13 14
+ 47 48 44 43 45 46 31 32 33 34 36 35
+ operation j=24 : 24 23 19 20 21 22 18 17 16 15 13 14
+ 37 38 39 40 42 41 7 8 9 10 12 11
+ 31 32 33 34 36 35 29 30 26 25 27 28
+ 44 43 47 48 46 45 2 1 4 3 6 5
+ operation j=25 : 25 26 30 29 28 27 43 44 45 46 48 47
+ 36 35 32 31 34 33 6 5 1 2 3 4
+ 40 39 41 42 37 38 20 19 23 24 22 21
+ 17 18 14 13 15 16 10 9 11 12 7 8
+ operation j=26 : 26 25 28 27 30 29 20 19 23 24 22 21
+ 35 36 34 33 32 31 5 6 3 4 1 2
+ 10 9 11 12 7 8 43 44 45 46 48 47
+ 14 13 17 18 16 15 40 39 41 42 37 38
+ operation j=27 : 27 28 29 30 26 25 45 46 43 44 47 48
+ 32 31 36 35 33 34 40 39 41 42 37 38
+ 6 5 1 2 3 4 14 13 17 18 16 15
+ 23 24 20 19 21 22 9 10 7 8 11 12
+ operation j=28 : 28 27 26 25 29 30 14 13 17 18 16 15
+ 31 32 33 34 36 35 39 40 37 38 41 42
+ 9 10 7 8 11 12 45 46 43 44 47 48
+ 20 19 23 24 22 21 6 5 1 2 3 4
+ operation j=29 : 29 30 27 28 25 26 23 24 20 19 21 22
+ 34 33 35 36 31 32 10 9 11 12 7 8
+ 5 6 3 4 1 2 17 18 14 13 15 16
+ 45 46 43 44 47 48 39 40 37 38 41 42
+ operation j=30 : 30 29 25 26 27 28 17 18 14 13 15 16
+ 33 34 31 32 35 36 9 10 7 8 11 12
+ 39 40 37 38 41 42 23 24 20 19 21 22
+ 43 44 45 46 48 47 5 6 3 4 1 2
+ operation j=31 : 31 32 35 36 34 33 2 1 4 3 5 6
+ 28 27 30 29 25 26 22 21 24 23 19 20
+ 48 47 46 45 44 43 8 7 12 11 10 9
+ 42 41 38 37 39 40 15 16 13 14 18 17
+ operation j=32 : 32 31 34 33 35 36 8 7 12 11 10 9
+ 27 28 25 26 30 29 21 22 19 20 24 23
+ 15 16 13 14 18 17 2 1 4 3 5 6
+ 38 37 42 41 40 39 48 47 46 45 44 43
+ operation j=33 : 33 34 36 35 32 31 4 3 2 1 6 5
+ 30 29 28 27 26 25 48 47 46 45 44 43
+ 22 21 24 23 19 20 38 37 42 41 40 39
+ 12 11 8 7 9 10 16 15 18 17 13 14
+ operation j=34 : 34 33 32 31 36 35 38 37 42 41 40 39
+ 29 30 26 25 28 27 47 48 44 43 46 45
+ 16 15 18 17 13 14 4 3 2 1 6 5
+ 8 7 12 11 10 9 22 21 24 23 19 20
+ operation j=35 : 35 36 31 32 33 34 42 41 38 37 39 40
+ 26 25 29 30 27 28 16 15 18 17 13 14
+ 47 48 44 43 46 45 12 11 8 7 9 10
+ 2 1 4 3 5 6 21 22 19 20 24 23
+ operation j=36 : 36 35 33 34 31 32 12 11 8 7 9 10
+ 25 26 27 28 29 30 15 16 13 14 18 17
+ 21 22 19 20 24 23 42 41 38 37 39 40
+ 4 3 2 1 6 5 47 48 44 43 46 45
+ operation j=37 : 37 38 41 42 40 39 3 4 5 6 1 2
+ 24 23 22 21 20 19 46 45 48 47 43 44
+ 28 27 30 29 25 26 34 33 35 36 32 31
+ 11 12 10 9 7 8 14 13 17 18 15 16
+ operation j=38 : 38 37 40 39 41 42 34 33 35 36 32 31
+ 23 24 20 19 22 21 45 46 43 44 48 47
+ 14 13 17 18 15 16 3 4 5 6 1 2
+ 10 9 11 12 8 7 28 27 30 29 25 26
+ operation j=39 : 39 40 42 41 38 37 5 6 3 4 2 1
+ 22 21 24 23 19 20 28 27 30 29 25 26
+ 46 45 48 47 43 44 10 9 11 12 8 7
+ 35 36 34 33 31 32 13 14 15 16 17 18
+ operation j=40 : 40 39 38 37 42 41 10 9 11 12 8 7
+ 21 22 19 20 24 23 27 28 25 26 30 29
+ 13 14 15 16 17 18 5 6 3 4 2 1
+ 34 33 35 36 32 31 46 45 48 47 43 44
+ operation j=41 : 41 42 37 38 39 40 11 12 10 9 7 8
+ 19 20 21 22 23 24 13 14 15 16 17 18
+ 27 28 25 26 30 29 35 36 34 33 31 32
+ 3 4 5 6 1 2 45 46 43 44 48 47
+ operation j=42 : 42 41 39 40 37 38 35 36 34 33 31 32
+ 20 19 23 24 21 22 14 13 17 18 15 16
+ 45 46 43 44 48 47 11 12 10 9 7 8
+ 5 6 3 4 2 1 27 28 25 26 30 29
+ operation j=43 : 43 44 48 47 46 45 25 26 27 28 30 29
+ 12 11 8 7 10 9 4 3 2 1 5 6
+ 38 37 42 41 39 40 19 20 21 22 24 23
+ 15 16 13 14 17 18 34 33 35 36 31 32
+ operation j=44 : 44 43 46 45 48 47 19 20 21 22 24 23
+ 11 12 10 9 8 7 3 4 5 6 2 1
+ 34 33 35 36 31 32 25 26 27 28 30 29
+ 13 14 15 16 18 17 38 37 42 41 39 40
+ operation j=45 : 45 46 47 48 44 43 27 28 25 26 29 30
+ 8 7 12 11 9 10 38 37 42 41 39 40
+ 4 3 2 1 5 6 13 14 15 16 18 17
+ 21 22 19 20 23 24 33 34 31 32 35 36
+ operation j=46 : 46 45 44 43 47 48 13 14 15 16 18 17
+ 7 8 9 10 12 11 37 38 39 40 42 41
+ 33 34 31 32 35 36 27 28 25 26 29 30
+ 19 20 21 22 24 23 4 3 2 1 5 6
+ operation j=47 : 47 48 45 46 43 44 21 22 19 20 23 24
+ 10 9 11 12 7 8 34 33 35 36 31 32
+ 3 4 5 6 2 1 15 16 13 14 17 18
+ 27 28 25 26 29 30 37 38 39 40 42 41
+ operation j=48 : 48 47 43 44 45 46 15 16 13 14 17 18
+ 9 10 7 8 11 12 33 34 31 32 35 36
+ 37 38 39 40 42 41 21 22 19 20 23 24
+ 25 26 27 28 30 29 3 4 5 6 2 1
+
+
+ Space group can be generated using 5 generators: 13 4 9 34 2
+
+ generators (in lattice coordinates):
+
+&gen 5
+
+ -1 0 0 0.00000
+ 0 -1 0 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+ 0 -1 1 0.00000
+
+ 0 1 -1 0.00000
+ 1 0 -1 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 1 0.00000
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+
+ -1 0 0 0.00000
+ -1 1 0 0.00000
+ -1 0 1 0.00000
+
+/ ! end generators
+
+
+
+ Atomic positions:
+ -----------------
+ atom types = 1
+ total = 1
+
+ lattice coordinates (scaled) Cartesian coordinates atom
+
+ atom type 1: atomic identification number = 74.0 representative = 1
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1
+
+atoms% 1 atoms 1
+ Z( 1)= 74 atoms 1
+ 0.000000 0.000000 0.000000 1
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+
+ ===============================================
+ === modifying atomic input for &(all)atom ===
+ ===============================================
+
+for atom 1 ( W) changed rmt to 2.100000
+for atom 1 ( W) changed jri to 981
+for atom 1 ( W) changed lmax to 12
+for atom 1 ( W) changed lnonsph to 6
+for atom 1 ( W) set econfig to [Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4
+ corestates = 16 with 60.0 electrons
+ valence st.= 5 with 14.0 electrons
+nlod = 2 llod = 1 : 5s5p
+ nlo( 1) = 2 llo = 0 1
+ lonqn = 5 5
+line: 13>&comp
+line: 14>gmax=15.0 gmaxxc=12.5 kmax=5.0 /
+ ----------
+ core : 1 -1 2.0
+ core : 2 -1 2.0
+ core : 2 1 2.0
+ core : 2 -2 4.0
+ core : 3 -1 2.0
+ core : 3 1 2.0
+ core : 3 -2 4.0
+ core : 3 2 4.0
+ core : 3 -3 6.0
+ core : 4 -1 2.0
+ core : 4 1 2.0
+ core : 4 -2 4.0
+ core : 4 2 4.0
+ core : 4 -3 6.0
+ core : 4 3 6.0
+ core : 4 -4 8.0
+ valence : 5 -1 2.0 5s
+ valence : 5 1 2.0 5p
+ valence : 5 -2 4.0 5p
+ valence : 6 -1 2.0 6s
+ valence : 5 2 2.0 5d
+ valence : 5 -3 2.0 5d
+ ----------
+Valence Electrons = 14
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+line: 15>&kpt
+line: 16>div1=3 div2=3 div3=3 tkb=0.0005 /
+ 5.22007561238382 5.22007561238382 5.22007561238382
+ -0.333333333333333 -0.333333333333333 -0.333333333333333
+ body centered cubic
+ values accepted unchanged
+ 3 3 3 nmop(i),i=1,3
+ orientation of boundary faces
+ 1 -1 -0.5740361 ifac,iside,orient for xvec
+ 2 -1 -0.0454288 ifac,iside,orient for xvec
+ 3 -1 -0.0256305 ifac,iside,orient for xvec
+ 4 -1 -0.0469244 ifac,iside,orient for xvec
+Bravais lattice vectors
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+reciprocal lattice vectors
+ 0.000000 1.042398 1.042398
+ 1.042398 0.000000 1.042398
+ 1.042398 1.042398 0.000000
+ 3 3 3 Monkhorst-Pack-parameters
+ 0 nreg; k-points in irreducible wedge of BZ
+ Monkhorst-Pack-fractions
+ 0 nbound; no k-points on boundary of BZ
+ 1 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 2 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 3 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+
+k-point count: 4
+
+k-point mesh: 3 3 3
+k-point density: 2.035038 2.035038 2.035038
+
diff --git a/tests/parsers/fixtures/inpgen/no_inpxml/out.error b/tests/parsers/fixtures/inpgen/no_inpxml/out.error
new file mode 100644
index 000000000..79c4a880f
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/no_inpxml/out.error
@@ -0,0 +1,2 @@
+ERROR
+Check_rmt
diff --git a/tests/parsers/fixtures/inpgen/no_otherfiles/inp.xml b/tests/parsers/fixtures/inpgen/no_otherfiles/inp.xml
new file mode 100644
index 000000000..2bf34f24c
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/no_otherfiles/inp.xml
@@ -0,0 +1,319 @@
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ -0.000000 0.333333 0.333333
+ -0.333333 0.333333 0.333333
+ -0.000000 0.000000 0.333333
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+
+
+
+
+ -3.013812060000000 3.013812060000000 3.013812060000000
+ 3.013812060000000 -3.013812060000000 3.013812060000000
+ 3.013812060000000 3.013812060000000 -3.013812060000000
+
+
+ |
+
+
+
+
+
+
+
+
+ [Kr] (4d3/2) (4d5/2) (4f5/2) (4f7/2)
+ (5s1/2) (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/inpgen/no_otherfiles/out.error b/tests/parsers/fixtures/inpgen/no_otherfiles/out.error
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/fixtures/inpgen/novalid_inpxml/inp.xml b/tests/parsers/fixtures/inpgen/novalid_inpxml/inp.xml
new file mode 100644
index 000000000..a203a82dd
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/novalid_inpxml/inp.xml
@@ -0,0 +1,319 @@
+
+
+
+ A Fleur input generator calculation with aiida
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+ -0.000000 0.333333 0.333333
+ -0.333333 0.333333 0.333333
+ -0.000000 0.000000 0.333333
+ 0.000000 0.000000 0.000000
+
+
+
+
+
+
+
+
+
+
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 0 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 1 0 -1 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+
+
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+
+
+ -1 0 0 .0000000000
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ -1 0 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 0 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ 0 0 -1 .0000000000
+ 0 -1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 1 0 -1 .0000000000
+ 1 -1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ 0 1 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 1 -1 .0000000000
+ -1 1 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+ 1 0 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+ 0 1 0 .0000000000
+
+
+ 1 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 0 -1 0 .0000000000
+
+
+ 0 -1 0 .0000000000
+ 0 -1 1 .0000000000
+ 1 -1 0 .0000000000
+
+
+ -1 1 0 .0000000000
+ -1 0 1 .0000000000
+ -1 0 0 .0000000000
+
+
+ 0 1 0 .0000000000
+ 0 0 1 .0000000000
+ 1 0 0 .0000000000
+
+
+ 1 0 0 .0000000000
+ 0 0 1 .0000000000
+ 0 1 0 .0000000000
+
+
+ -1 0 0 .0000000000
+ -1 0 1 .0000000000
+ -1 1 0 .0000000000
+
+
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+
+
+ 0 0 1 .0000000000
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ -1 0 1 .0000000000
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ 0 0 1 .0000000000
+ -1 0 1 .0000000000
+
+
+ 0 -1 1 .0000000000
+ -1 0 1 .0000000000
+ 0 0 1 .0000000000
+
+
+
+
+ -3.013812060000000 3.013812060000000 3.013812060000000
+ 3.013812060000000 -3.013812060000000 3.013812060000000
+ 3.013812060000000 3.013812060000000 -3.013812060000000
+
+
+ |
+
+
+
+
+
+
+
+
+ [Kr] (4d3/2) (4d5/2) (4f5/2) (4f7/2)
+ (5s1/2) (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
+
+
+
+
+
+
+
+
+
+ .0000000000 .0000000000 .0000000000
+
+
+
+
+
+
+
+
diff --git a/tests/parsers/fixtures/inpgen/novalid_inpxml/out b/tests/parsers/fixtures/inpgen/novalid_inpxml/out
new file mode 100644
index 000000000..fca99897b
--- /dev/null
+++ b/tests/parsers/fixtures/inpgen/novalid_inpxml/out
@@ -0,0 +1,687 @@
+line: 1>A Fleur input generator calculation with aiida
+line: 2>&input cartesian=F /
+line: 3>-3.0138120600 3.0138120600 3.0138120600
+line: 4>3.0138120600 -3.0138120600 3.0138120600
+line: 5>3.0138120600 3.0138120600 -3.0138120600
+line: 6>1.0000000000
+line: 7>1.0000000000 1.0000000000 1.0000000000
+line: 8>
+line: 9>1
+line: 10>74 0.0000000000 0.0000000000 0.0000000000
+line: 11>&atom
+line: 12>econfig="[Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4" element="W" jri=981 lm
+
+ A Fleur input generator calculation with aiida
+
+ film= F cartesian= F
+ checkinp= F symor= F
+
+a1 = -3.01381 3.01381 3.01381
+a2 = 3.01381 -3.01381 3.01381
+a3 = 3.01381 3.01381 -3.01381
+
+dvac= -3.01381 aa = 1.00000
+scale = 1.00000 1.00000 1.00000
+
+natin= 1 Z = 74
+ positions:
+ 0.00000 0.00000 0.00000
+
+ generators: 0 (excluding identity)
+
+
+ Lattice information:
+ --------------------
+
+ overall lattice constant a0 = 1.000000 bohr
+
+ real-space primitive lattice vectors in units of a_{x,y,z}
+ a_1: -3.013812 3.013812 3.013812
+ a_2: 3.013812 -3.013812 3.013812
+ a_3: 3.013812 3.013812 -3.013812
+
+ lattice constants a_x, a_y, a_z = 1.000000 1.000000 1.000000
+ volume of unit cell (a.u.^3) = 109.498581
+
+dbg: lattice matrices
+ 109.498580847925
+dbg: as :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bs :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: amat :
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+dbg: bmat :
+ 0.000000 0.521199 0.521199
+ 0.521199 0.000000 0.521199
+ 0.521199 0.521199 0.000000
+dbg: amatinv :
+ 0.000000 0.165903 0.165903
+ 0.165903 0.000000 0.165903
+ 0.165903 0.165903 0.000000
+dbg: aamat :
+ 27.249189 -9.083063 -9.083063
+ -9.083063 27.249189 -9.083063
+ -9.083063 -9.083063 27.249189
+dbg: bbmat :
+ 0.543297 0.271649 0.271649
+ 0.271649 0.543297 0.271649
+ 0.271649 0.271649 0.543297
+
+dbg: lattice vectors :
+vector 1 : -3.01381 3.01381 3.01381 length : 5.22008
+vector 2 : 3.01381 -3.01381 3.01381 length : 5.22008
+vector 3 : 3.01381 3.01381 -3.01381 length : 5.22008
+angle between vectors (1,2) =109.47122
+angle between vectors (1,3) =109.47122
+angle between vectors (2,3) =109.47122
+
+dbg: reciprocal lattice vectors :
+vector 1 : 0.00000 0.52120 0.52120 length : 0.73709
+vector 2 : 0.52120 0.00000 0.52120 length : 0.73709
+vector 3 : 0.52120 0.52120 0.00000 length : 0.73709
+angle between vectors (1,2) = 60.00000
+angle between vectors (1,3) = 60.00000
+angle between vectors (2,3) = 60.00000
+
+
+ Point group of the Bravais lattice has 48 operations
+
+ DBG: symor,zorth,oldfleur : T F F
+ DBG: optype : 1 -2 -2 3 3 -2 -2 3 2 -4 3 -4 -1 2 2 -3 -3 2 2 -2 -3 4 4 -3 -3 4 2 -3 -2 4 3 -2 -4 2 -4 3 3 -4 -4 3 -2 2 4 -3 -3 2 4 -2
+ DBG: invsym,invs,zrfs,invs2 : T T F F
+ DBG: (before reorder) invsop,zrfsop,invs2op : 13 7 46
+
+ Space group information:
+ ------------------------
+ 48 operations
+ space group is symmorphic
+ has inversion symmetry
+
+
+ Operations: (in International notation)
+ ---------------------------------------
+ lattice coordinates (scaled) Cartesian coordinates
+
+ operation 1: 1 (inverse = 1)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 2: 2 (inverse = 2)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 3: 2 (inverse = 3)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 4: 3 (inverse = 5)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+
+ operation 5: 3 (inverse = 4)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 6: 2 (inverse = 6)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 7: 2 (inverse = 7)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 8: 3 (inverse = 31)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 9: 2 (inverse = 9)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 10: 4 (inverse = 33)
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 11: 3 (inverse = 37)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 12: 4 (inverse = 39)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 13: 1 (inverse = 13)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 14: 2 (inverse = 14)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 15: 2 (inverse = 15)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 16: 3 (inverse = 17)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 17: 3 (inverse = 16)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 18: 2 (inverse = 18)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+
+ operation 19: 2 (inverse = 19)
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 20: 2 (inverse = 20)
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 21: 3 (inverse = 25)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 -1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 22: 4 (inverse = 43)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 -1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+
+ operation 23: 4 (inverse = 26)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ _
+ operation 24: 3 (inverse = 44)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 25: 3 (inverse = 21)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+
+ operation 26: 4 (inverse = 23)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+
+ operation 27: 2 (inverse = 27)
+ ( 0 0 -1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 28: 3 (inverse = 45)
+ ( 1 0 -1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 29: 2 (inverse = 29)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+
+ operation 30: 4 (inverse = 47)
+ ( 0 1 -1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+
+ operation 31: 3 (inverse = 8)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 32: 2 (inverse = 32)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 33: 4 (inverse = 10)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 34: 2 (inverse = 34)
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 35: 4 (inverse = 38)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 36: 3 (inverse = 40)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 37: 3 (inverse = 11)
+ ( 1 -1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 38: 4 (inverse = 35)
+ ( 0 -1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( -1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 1 -1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ _
+ operation 39: 4 (inverse = 12)
+ ( -1 1 0 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 -1.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+
+ operation 40: 3 (inverse = 36)
+ ( 0 1 0 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 1.00000 ) ( 0.000 )
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ _
+ operation 41: 2 (inverse = 41)
+ ( 1 0 0 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 1.00000 ) ( 0.000 )
+ ( 0 1 0 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+
+ operation 42: 2 (inverse = 42)
+ ( -1 0 0 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 -1.00000 0.00000 ) ( 0.000 )
+ ( -1 1 0 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+
+ operation 43: 4 (inverse = 22)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 44: 3 (inverse = 24)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 0.00000 ) ( 0.000 )
+ _
+ operation 45: 3 (inverse = 28)
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 0.00000 -1.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 -0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+
+ operation 46: 2 (inverse = 46)
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 -0.00000 ) ( 0.000 )
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ operation 47: 4 (inverse = 30)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( 0.00000 -0.00000 -1.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( -0.00000 1.00000 0.00000 ) ( 0.000 )
+ _
+ operation 48: 2 (inverse = 48)
+ ( 0 -1 1 ) ( 0.000 ) ( 1.00000 0.00000 -0.00000 ) ( 0.000 )
+ ( -1 0 1 ) ( 0.000 ) ( 0.00000 1.00000 0.00000 ) ( 0.000 )
+ ( 0 0 1 ) ( 0.000 ) ( -0.00000 -0.00000 -1.00000 ) ( 0.000 )
+
+ Multiplcation table: {R_j|t_j}{R_i|t_i}
+ operation j= 1 : 1 2 3 4 5 6 7 8 9 10 11 12
+ 13 14 15 16 17 18 19 20 21 22 23 24
+ 25 26 27 28 29 30 31 32 33 34 35 36
+ 37 38 39 40 41 42 43 44 45 46 47 48
+ operation j= 2 : 2 1 5 6 3 4 31 32 33 34 35 36
+ 14 13 17 18 15 16 20 19 23 24 21 22
+ 43 44 45 46 47 48 7 8 9 10 11 12
+ 39 40 37 38 42 41 25 26 27 28 29 30
+ operation j= 3 : 3 4 1 2 6 5 37 38 39 40 41 42
+ 18 17 16 15 14 13 44 43 47 48 45 46
+ 26 25 29 30 27 28 33 34 31 32 36 35
+ 7 8 9 10 11 12 20 19 23 24 21 22
+ operation j= 4 : 4 3 6 5 1 2 33 34 31 32 36 35
+ 17 18 14 13 16 15 43 44 45 46 47 48
+ 20 19 23 24 21 22 37 38 39 40 41 42
+ 9 10 7 8 12 11 26 25 29 30 27 28
+ operation j= 5 : 5 6 2 1 4 3 39 40 37 38 42 41
+ 16 15 18 17 13 14 26 25 29 30 27 28
+ 44 43 47 48 45 46 9 10 7 8 12 11
+ 31 32 33 34 35 36 19 20 21 22 23 24
+ operation j= 6 : 6 5 4 3 2 1 9 10 7 8 12 11
+ 15 16 13 14 18 17 25 26 27 28 29 30
+ 19 20 21 22 23 24 39 40 37 38 42 41
+ 33 34 31 32 36 35 44 43 47 48 45 46
+ operation j= 7 : 7 8 11 12 10 9 1 2 6 5 3 4
+ 46 45 48 47 43 44 24 23 22 21 20 19
+ 30 29 28 27 26 25 32 31 36 35 34 33
+ 41 42 40 39 37 38 17 18 14 13 16 15
+ operation j= 8 : 8 7 10 9 11 12 32 31 36 35 34 33
+ 45 46 43 44 48 47 23 24 20 19 22 21
+ 17 18 14 13 16 15 1 2 6 5 3 4
+ 40 39 41 42 38 37 30 29 28 27 26 25
+ operation j= 9 : 9 10 12 11 8 7 6 5 1 2 4 3
+ 48 47 46 45 44 43 30 29 28 27 26 25
+ 24 23 22 21 20 19 40 39 41 42 38 37
+ 36 35 32 31 33 34 18 17 16 15 14 13
+ operation j=10 : 10 9 8 7 12 11 40 39 41 42 38 37
+ 47 48 44 43 46 45 29 30 26 25 28 27
+ 18 17 16 15 14 13 6 5 1 2 4 3
+ 32 31 36 35 34 33 24 23 22 21 20 19
+ operation j=11 : 11 12 7 8 9 10 41 42 40 39 37 38
+ 44 43 47 48 45 46 18 17 16 15 14 13
+ 29 30 26 25 28 27 36 35 32 31 33 34
+ 1 2 6 5 3 4 23 24 20 19 22 21
+ operation j=12 : 12 11 9 10 7 8 36 35 32 31 33 34
+ 43 44 45 46 47 48 17 18 14 13 16 15
+ 23 24 20 19 22 21 41 42 40 39 37 38
+ 6 5 1 2 4 3 29 30 26 25 28 27
+ operation j=13 : 13 14 18 17 16 15 46 45 48 47 44 43
+ 1 2 6 5 4 3 41 42 40 39 38 37
+ 36 35 32 31 34 33 28 27 30 29 26 25
+ 24 23 22 21 19 20 12 11 8 7 10 9
+ operation j=14 : 14 13 16 15 18 17 28 27 30 29 26 25
+ 2 1 4 3 6 5 42 41 38 37 40 39
+ 12 11 8 7 10 9 46 45 48 47 44 43
+ 22 21 24 23 20 19 36 35 32 31 34 33
+ operation j=15 : 15 16 17 18 14 13 48 47 46 45 43 44
+ 6 5 1 2 3 4 36 35 32 31 34 33
+ 41 42 40 39 38 37 22 21 24 23 20 19
+ 30 29 28 27 25 26 11 12 10 9 8 7
+ operation j=16 : 16 15 14 13 17 18 22 21 24 23 20 19
+ 5 6 3 4 1 2 35 36 34 33 32 31
+ 11 12 10 9 8 7 48 47 46 45 43 44
+ 28 27 30 29 26 25 41 42 40 39 38 37
+ operation j=17 : 17 18 15 16 13 14 30 29 28 27 25 26
+ 4 3 2 1 5 6 12 11 8 7 10 9
+ 42 41 38 37 40 39 24 23 22 21 19 20
+ 48 47 46 45 43 44 35 36 34 33 32 31
+ operation j=18 : 18 17 13 14 15 16 24 23 22 21 19 20
+ 3 4 5 6 2 1 11 12 10 9 8 7
+ 35 36 34 33 32 31 30 29 28 27 25 26
+ 46 45 48 47 44 43 42 41 38 37 40 39
+ operation j=19 : 19 20 24 23 22 21 44 43 47 48 46 45
+ 41 42 40 39 38 37 1 2 6 5 4 3
+ 32 31 36 35 33 34 26 25 29 30 28 27
+ 18 17 16 15 13 14 8 7 12 11 9 10
+ operation j=20 : 20 19 22 21 24 23 26 25 29 30 28 27
+ 42 41 38 37 40 39 2 1 4 3 6 5
+ 8 7 12 11 9 10 44 43 47 48 46 45
+ 16 15 18 17 14 13 32 31 36 35 33 34
+ operation j=21 : 21 22 23 24 20 19 47 48 44 43 45 46
+ 40 39 41 42 37 38 32 31 36 35 33 34
+ 1 2 6 5 4 3 16 15 18 17 14 13
+ 29 30 26 25 27 28 7 8 9 10 12 11
+ operation j=22 : 22 21 20 19 23 24 16 15 18 17 14 13
+ 39 40 37 38 41 42 31 32 33 34 36 35
+ 7 8 9 10 12 11 47 48 44 43 45 46
+ 26 25 29 30 28 27 1 2 6 5 4 3
+ operation j=23 : 23 24 21 22 19 20 29 30 26 25 27 28
+ 38 37 42 41 39 40 8 7 12 11 9 10
+ 2 1 4 3 6 5 18 17 16 15 13 14
+ 47 48 44 43 45 46 31 32 33 34 36 35
+ operation j=24 : 24 23 19 20 21 22 18 17 16 15 13 14
+ 37 38 39 40 42 41 7 8 9 10 12 11
+ 31 32 33 34 36 35 29 30 26 25 27 28
+ 44 43 47 48 46 45 2 1 4 3 6 5
+ operation j=25 : 25 26 30 29 28 27 43 44 45 46 48 47
+ 36 35 32 31 34 33 6 5 1 2 3 4
+ 40 39 41 42 37 38 20 19 23 24 22 21
+ 17 18 14 13 15 16 10 9 11 12 7 8
+ operation j=26 : 26 25 28 27 30 29 20 19 23 24 22 21
+ 35 36 34 33 32 31 5 6 3 4 1 2
+ 10 9 11 12 7 8 43 44 45 46 48 47
+ 14 13 17 18 16 15 40 39 41 42 37 38
+ operation j=27 : 27 28 29 30 26 25 45 46 43 44 47 48
+ 32 31 36 35 33 34 40 39 41 42 37 38
+ 6 5 1 2 3 4 14 13 17 18 16 15
+ 23 24 20 19 21 22 9 10 7 8 11 12
+ operation j=28 : 28 27 26 25 29 30 14 13 17 18 16 15
+ 31 32 33 34 36 35 39 40 37 38 41 42
+ 9 10 7 8 11 12 45 46 43 44 47 48
+ 20 19 23 24 22 21 6 5 1 2 3 4
+ operation j=29 : 29 30 27 28 25 26 23 24 20 19 21 22
+ 34 33 35 36 31 32 10 9 11 12 7 8
+ 5 6 3 4 1 2 17 18 14 13 15 16
+ 45 46 43 44 47 48 39 40 37 38 41 42
+ operation j=30 : 30 29 25 26 27 28 17 18 14 13 15 16
+ 33 34 31 32 35 36 9 10 7 8 11 12
+ 39 40 37 38 41 42 23 24 20 19 21 22
+ 43 44 45 46 48 47 5 6 3 4 1 2
+ operation j=31 : 31 32 35 36 34 33 2 1 4 3 5 6
+ 28 27 30 29 25 26 22 21 24 23 19 20
+ 48 47 46 45 44 43 8 7 12 11 10 9
+ 42 41 38 37 39 40 15 16 13 14 18 17
+ operation j=32 : 32 31 34 33 35 36 8 7 12 11 10 9
+ 27 28 25 26 30 29 21 22 19 20 24 23
+ 15 16 13 14 18 17 2 1 4 3 5 6
+ 38 37 42 41 40 39 48 47 46 45 44 43
+ operation j=33 : 33 34 36 35 32 31 4 3 2 1 6 5
+ 30 29 28 27 26 25 48 47 46 45 44 43
+ 22 21 24 23 19 20 38 37 42 41 40 39
+ 12 11 8 7 9 10 16 15 18 17 13 14
+ operation j=34 : 34 33 32 31 36 35 38 37 42 41 40 39
+ 29 30 26 25 28 27 47 48 44 43 46 45
+ 16 15 18 17 13 14 4 3 2 1 6 5
+ 8 7 12 11 10 9 22 21 24 23 19 20
+ operation j=35 : 35 36 31 32 33 34 42 41 38 37 39 40
+ 26 25 29 30 27 28 16 15 18 17 13 14
+ 47 48 44 43 46 45 12 11 8 7 9 10
+ 2 1 4 3 5 6 21 22 19 20 24 23
+ operation j=36 : 36 35 33 34 31 32 12 11 8 7 9 10
+ 25 26 27 28 29 30 15 16 13 14 18 17
+ 21 22 19 20 24 23 42 41 38 37 39 40
+ 4 3 2 1 6 5 47 48 44 43 46 45
+ operation j=37 : 37 38 41 42 40 39 3 4 5 6 1 2
+ 24 23 22 21 20 19 46 45 48 47 43 44
+ 28 27 30 29 25 26 34 33 35 36 32 31
+ 11 12 10 9 7 8 14 13 17 18 15 16
+ operation j=38 : 38 37 40 39 41 42 34 33 35 36 32 31
+ 23 24 20 19 22 21 45 46 43 44 48 47
+ 14 13 17 18 15 16 3 4 5 6 1 2
+ 10 9 11 12 8 7 28 27 30 29 25 26
+ operation j=39 : 39 40 42 41 38 37 5 6 3 4 2 1
+ 22 21 24 23 19 20 28 27 30 29 25 26
+ 46 45 48 47 43 44 10 9 11 12 8 7
+ 35 36 34 33 31 32 13 14 15 16 17 18
+ operation j=40 : 40 39 38 37 42 41 10 9 11 12 8 7
+ 21 22 19 20 24 23 27 28 25 26 30 29
+ 13 14 15 16 17 18 5 6 3 4 2 1
+ 34 33 35 36 32 31 46 45 48 47 43 44
+ operation j=41 : 41 42 37 38 39 40 11 12 10 9 7 8
+ 19 20 21 22 23 24 13 14 15 16 17 18
+ 27 28 25 26 30 29 35 36 34 33 31 32
+ 3 4 5 6 1 2 45 46 43 44 48 47
+ operation j=42 : 42 41 39 40 37 38 35 36 34 33 31 32
+ 20 19 23 24 21 22 14 13 17 18 15 16
+ 45 46 43 44 48 47 11 12 10 9 7 8
+ 5 6 3 4 2 1 27 28 25 26 30 29
+ operation j=43 : 43 44 48 47 46 45 25 26 27 28 30 29
+ 12 11 8 7 10 9 4 3 2 1 5 6
+ 38 37 42 41 39 40 19 20 21 22 24 23
+ 15 16 13 14 17 18 34 33 35 36 31 32
+ operation j=44 : 44 43 46 45 48 47 19 20 21 22 24 23
+ 11 12 10 9 8 7 3 4 5 6 2 1
+ 34 33 35 36 31 32 25 26 27 28 30 29
+ 13 14 15 16 18 17 38 37 42 41 39 40
+ operation j=45 : 45 46 47 48 44 43 27 28 25 26 29 30
+ 8 7 12 11 9 10 38 37 42 41 39 40
+ 4 3 2 1 5 6 13 14 15 16 18 17
+ 21 22 19 20 23 24 33 34 31 32 35 36
+ operation j=46 : 46 45 44 43 47 48 13 14 15 16 18 17
+ 7 8 9 10 12 11 37 38 39 40 42 41
+ 33 34 31 32 35 36 27 28 25 26 29 30
+ 19 20 21 22 24 23 4 3 2 1 5 6
+ operation j=47 : 47 48 45 46 43 44 21 22 19 20 23 24
+ 10 9 11 12 7 8 34 33 35 36 31 32
+ 3 4 5 6 2 1 15 16 13 14 17 18
+ 27 28 25 26 29 30 37 38 39 40 42 41
+ operation j=48 : 48 47 43 44 45 46 15 16 13 14 17 18
+ 9 10 7 8 11 12 33 34 31 32 35 36
+ 37 38 39 40 42 41 21 22 19 20 23 24
+ 25 26 27 28 30 29 3 4 5 6 2 1
+
+
+ Space group can be generated using 5 generators: 13 4 9 34 2
+
+ generators (in lattice coordinates):
+
+&gen 5
+
+ -1 0 0 0.00000
+ 0 -1 0 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+ 0 -1 1 0.00000
+
+ 0 1 -1 0.00000
+ 1 0 -1 0.00000
+ 0 0 -1 0.00000
+
+ 0 -1 1 0.00000
+ 0 -1 0 0.00000
+ 1 -1 0 0.00000
+
+ -1 0 0 0.00000
+ -1 1 0 0.00000
+ -1 0 1 0.00000
+
+/ ! end generators
+
+
+
+ Atomic positions:
+ -----------------
+ atom types = 1
+ total = 1
+
+ lattice coordinates (scaled) Cartesian coordinates atom
+
+ atom type 1: atomic identification number = 74.0 representative = 1
+ 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000 1
+
+atoms% 1 atoms 1
+ Z( 1)= 74 atoms 1
+ 0.000000 0.000000 0.000000 1
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+
+ ===============================================
+ === modifying atomic input for &(all)atom ===
+ ===============================================
+
+for atom 1 ( W) changed rmt to 2.100000
+for atom 1 ( W) changed jri to 981
+for atom 1 ( W) changed lmax to 12
+for atom 1 ( W) changed lnonsph to 6
+for atom 1 ( W) set econfig to [Kr] 4d10 4f14 | 5s2 5p6 6s2 5d4
+ corestates = 16 with 60.0 electrons
+ valence st.= 5 with 14.0 electrons
+nlod = 2 llod = 1 : 5s5p
+ nlo( 1) = 2 llo = 0 1
+ lonqn = 5 5
+line: 13>&comp
+line: 14>gmax=15.0 gmaxxc=12.5 kmax=5.0 /
+ ----------
+ core : 1 -1 2.0
+ core : 2 -1 2.0
+ core : 2 1 2.0
+ core : 2 -2 4.0
+ core : 3 -1 2.0
+ core : 3 1 2.0
+ core : 3 -2 4.0
+ core : 3 2 4.0
+ core : 3 -3 6.0
+ core : 4 -1 2.0
+ core : 4 1 2.0
+ core : 4 -2 4.0
+ core : 4 2 4.0
+ core : 4 -3 6.0
+ core : 4 3 6.0
+ core : 4 -4 8.0
+ valence : 5 -1 2.0 5s
+ valence : 5 1 2.0 5p
+ valence : 5 -2 4.0 5p
+ valence : 6 -1 2.0 6s
+ valence : 5 2 2.0 5d
+ valence : 5 -3 2.0 5d
+ ----------
+Valence Electrons = 14
+ ----------------------------------------------------
+ Suggested values for input:
+
+ Atom Z lmax jri rmt dx
+ W 74 10 841 2.544787 0.015844
+k_max = 3.92960
+G_max =11.78881
+line: 15>&kpt
+line: 16>div1=3 div2=3 div3=3 tkb=0.0005 /
+ 5.22007561238382 5.22007561238382 5.22007561238382
+ -0.333333333333333 -0.333333333333333 -0.333333333333333
+ body centered cubic
+ values accepted unchanged
+ 3 3 3 nmop(i),i=1,3
+ orientation of boundary faces
+ 1 -1 -0.5740361 ifac,iside,orient for xvec
+ 2 -1 -0.0454288 ifac,iside,orient for xvec
+ 3 -1 -0.0256305 ifac,iside,orient for xvec
+ 4 -1 -0.0469244 ifac,iside,orient for xvec
+Bravais lattice vectors
+ -3.013812 3.013812 3.013812
+ 3.013812 -3.013812 3.013812
+ 3.013812 3.013812 -3.013812
+reciprocal lattice vectors
+ 0.000000 1.042398 1.042398
+ 1.042398 0.000000 1.042398
+ 1.042398 1.042398 0.000000
+ 3 3 3 Monkhorst-Pack-parameters
+ 0 nreg; k-points in irreducible wedge of BZ
+ Monkhorst-Pack-fractions
+ 0 nbound; no k-points on boundary of BZ
+ 1 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 2 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+ 3 idim
+ -0.3333333
+ 0.0000000
+ 0.3333333
+
+k-point count: 4
+
+k-point mesh: 3 3 3
+k-point density: 2.035038 2.035038 2.035038
+
diff --git a/tests/parsers/fixtures/inpgen/novalid_inpxml/out.error b/tests/parsers/fixtures/inpgen/novalid_inpxml/out.error
new file mode 100644
index 000000000..e69de29bb
diff --git a/tests/parsers/test_fleur_parser.py b/tests/parsers/test_fleur_parser.py
index b7737651e..e6cbe1a1b 100644
--- a/tests/parsers/test_fleur_parser.py
+++ b/tests/parsers/test_fleur_parser.py
@@ -1,10 +1,19 @@
# -*- coding: utf-8 -*-
-''' Contains tests for routines used by the fleur parser. '''
+''' Contains tests for the fleur parser and its routines. '''
from __future__ import absolute_import
import os
import pytest
import math
+from aiida.common import AttributeDict
+from aiida import orm
+import aiida_fleur
+#TODO use pytest-regression for full dict tests, easier to update if parser changes.
+
+aiida_path = os.path.dirname(aiida_fleur.__file__)
+TEST_INP_XML_PATH = os.path.join(aiida_path, '../tests/files/inpxml/Si/inp.xml')
+# for relaxation path
+TEST_INP_XML_PATH1 = os.path.join(aiida_path, '../tests/parsers/fixtures/fleur/relax/inp.xml')
# parse_xmlout_file
@@ -28,7 +37,7 @@ def test_parse_xmlout_file():
'creator_target_architecture': 'GEN',
'creator_target_structure': ' ',
'density_convergence_units': 'me/bohr^3',
- 'energy': -23635.691764717936,
+ 'energy': -23635.691961010132,
'energy_core_electrons': -496.172547773,
'energy_hartree': -868.5956587197,
'energy_hartree_units': 'Htr',
@@ -67,7 +76,7 @@ def test_parse_xmlout_file():
}
}
- expected_parser_info_out = {'parser_info': 'AiiDA Fleur Parser v0.3.0', 'parser_warnings': [], 'unparsed': []}
+ expected_parser_info_out = {'parser_info': 'AiiDA Fleur Parser v0.3.2', 'parser_warnings': [], 'unparsed': []}
simple_out.pop('outputfile_path', None) # otherwise test will fail on different installations
# also this should go away any way...
@@ -93,7 +102,7 @@ def test_parse_xmlout_file_broken_xmlout_file():
'last_iteration_parsed':
15,
'parser_info':
- 'AiiDA Fleur Parser v0.3.0',
+ 'AiiDA Fleur Parser v0.3.2',
'parser_warnings': [
'The out.xml file is broken I try to repair it.',
'Endtime was unparsed, inp.xml prob not complete, do not believe the walltime!'
@@ -123,7 +132,7 @@ def test_parse_xmlout_file_broken_first_xmlout_file():
'last_iteration_parsed':
1,
'parser_info':
- 'AiiDA Fleur Parser v0.3.0',
+ 'AiiDA Fleur Parser v0.3.2',
'parser_warnings': [
'The out.xml file is broken I try to repair it.',
'Can not get attributename: "units" from node "[]", because node is not an element of etree.',
@@ -212,7 +221,7 @@ def test_parse_xmlout_file_fortran_garbage_in_xmlout_file():
expected_parser_info_out = {
'parser_info':
- 'AiiDA Fleur Parser v0.3.0',
+ 'AiiDA Fleur Parser v0.3.2',
'parser_warnings': [
'Could not convert: "**" to float, ValueError',
'Could not convert: " !#@)!(U$*(Y" to float, ValueError'
@@ -252,7 +261,7 @@ def test_parse_xmlout_file_empty_file():
expected_parser_info_out = {
'parser_info':
- 'AiiDA Fleur Parser v0.3.0',
+ 'AiiDA Fleur Parser v0.3.2',
'parser_warnings': [
'The out.xml file is broken I try to repair it.',
'Skipping the parsing of the xml file. Repairing was not possible.'
@@ -288,6 +297,18 @@ def test_fleurparse_all_xmlout_file(xmloutfile):
assert successful
+def test_fleurparse_relax_file():
+ """Test if parsing of a given relax.xml file is successfull"""
+ from aiida_fleur.parsers.fleur import parse_relax_file
+ from aiida.orm import Dict
+
+ filename = os.path.abspath('./files/relaxxml/Fe_relax.xml')
+ with open(filename, 'r') as relaxfile:
+ result = parse_relax_file(relaxfile)
+ assert isinstance(result, Dict)
+ assert result.get_dict() != {}
+
+
# parse_dos_file, test for different dos files with spin and without
@pytest.mark.skip(reason='Test is not implemented')
def test_parse_dos_file():
@@ -317,3 +338,199 @@ def test_parse_bands_file():
# test if the right aiida datastructures are produced for different output
# also check if errors are working...
# if an empty and broken file works, broken before and after first iteration
+
+
+def test_fleur_parser_default_full(fixture_localhost, generate_parser, generate_calc_job_node, create_fleurinp,
+ data_regression):
+ """
+ Default inpgen parser test of a successful inpgen calculation.
+ Checks via data regression if attributes of outputparamters are the same
+ """
+
+ name = 'default'
+ entry_point_calc_job = 'fleur.fleur'
+ entry_point_parser = 'fleur.fleurparser'
+
+ inputs = AttributeDict({'fleurinp': create_fleurinp(TEST_INP_XML_PATH), 'metadata': {}})
+
+ #change retrieve list to save space
+ retrieve_list = [
+ 'out.xml', 'inp.xml', 'shell.out', 'out.error', 'cdn1', '_scheduler-stdout.txt', '_scheduler-stderr.txt'
+ ]
+ node = generate_calc_job_node(entry_point_calc_job,
+ fixture_localhost,
+ name,
+ inputs,
+ store=True,
+ retrieve_list=retrieve_list)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_finished_ok, calcfunction.exit_message
+ assert not orm.Log.objects.get_logs_for(node), [log.message for log in orm.Log.objects.get_logs_for(node)]
+ assert 'output_parameters' in results
+ assert 'output_params_complex' not in results
+ assert 'relax_parameters' not in results
+ assert 'error_params' not in results
+
+ data_regression.check({
+ 'output_parameters': clean_outdict_for_reg_dump(results['output_parameters'].get_dict()),
+ })
+
+
+'''
+def test_fleur_parser_band_dos(fixture_localhost, generate_parser, generate_calc_job_node, create_fleurinp, data_regression):
+ """
+ Default inpgen parser test of a successful inpgen calculation.
+ Checks via data regression if attributes of fleurinp are the same
+ """
+
+ name = 'band_dos'
+ entry_point_calc_job = 'fleur.fleur'
+ entry_point_parser = 'fleur.fleurparser'
+
+ inputs = AttributeDict({'fleurinp': create_fleurinp(TEST_INP_XML_PATH),
+ 'metadata' : {}})
+
+ #change retrieve list to save space
+ retrieve_list = ['out.xml', 'inp.xml', 'shell.out', 'out.error','cdn1','_scheduler-stdout.txt','_scheduler-stderr.txt']
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True, retrieve_list=retrieve_list)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_finished_ok, calcfunction.exit_message
+ assert not orm.Log.objects.get_logs_for(node), [log.message for log in orm.Log.objects.get_logs_for(node)]
+ assert 'output_parameters' in results
+ assert 'output_params_complex' not in results
+ assert 'relax_parameters' not in results
+ assert 'error_params' not in results
+
+ data_regression.check({
+ 'output_parameters': results['output_parameters'].attributes,
+ })
+'''
+
+
+def test_fleur_parser_relax(fixture_localhost, generate_parser, generate_calc_job_node, create_fleurinp,
+ data_regression):
+ """
+ Default inpgen parser test of a successful inpgen calculation.
+ Checks via data regression if attributes of fleurinp are the same
+ """
+
+ name = 'relax'
+ entry_point_calc_job = 'fleur.fleur'
+ entry_point_parser = 'fleur.fleurparser'
+
+ inputs = AttributeDict({'fleurinp': create_fleurinp(TEST_INP_XML_PATH1), 'metadata': {}})
+
+ #change retrieve list to save space
+ retrieve_list = ['out.xml', 'out.error', 'relax.xml']
+ node = generate_calc_job_node(entry_point_calc_job,
+ fixture_localhost,
+ name,
+ inputs,
+ store=True,
+ retrieve_list=retrieve_list)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_finished_ok, calcfunction.exit_message
+ assert not orm.Log.objects.get_logs_for(node), [log.message for log in orm.Log.objects.get_logs_for(node)]
+ assert 'output_parameters' in results
+ assert 'output_params_complex' not in results
+ assert 'relax_parameters' in results
+ assert 'error_params' not in results
+
+ data_regression.check({
+ 'output_parameters': clean_outdict_for_reg_dump(results['output_parameters'].get_dict()),
+ 'relax_parameters': results['relax_parameters'].get_dict()
+ })
+
+
+def test_fleur_parser_MT_overlap_erroroutput(fixture_localhost, generate_parser, generate_calc_job_node,
+ create_fleurinp, data_regression):
+ """
+ Default inpgen parser test of a failed fleur calculation.
+ """
+
+ name = 'mt_overlap_errorout'
+ entry_point_calc_job = 'fleur.fleur'
+ entry_point_parser = 'fleur.fleurparser'
+
+ inputs = AttributeDict({'fleurinp': create_fleurinp(TEST_INP_XML_PATH1), 'metadata': {}})
+
+ #change retrieve list to save space
+ retrieve_list = ['out.xml', 'out.error', 'relax.xml']
+ node = generate_calc_job_node(entry_point_calc_job,
+ fixture_localhost,
+ name,
+ inputs,
+ store=True,
+ retrieve_list=retrieve_list)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_MT_RADII_RELAX.status
+ assert 'output_parameters' not in results
+ assert 'output_params_complex' not in results
+ assert 'relax_parameters' not in results
+ assert 'error_params' in results
+ data_regression.check({'error_params': results['error_params'].get_dict()})
+
+
+def test_fleur_parser_complex_erroroutput(fixture_localhost, generate_parser, generate_calc_job_node, create_fleurinp,
+ data_regression):
+ """
+ Default inpgen parser test of a successful inpgen calculation.
+ Checks via data regression if attributes of fleurinp are the same
+ """
+
+ name = 'complex_errorout'
+ entry_point_calc_job = 'fleur.fleur'
+ entry_point_parser = 'fleur.fleurparser'
+
+ inputs = AttributeDict({'fleurinp': create_fleurinp(TEST_INP_XML_PATH), 'metadata': {}})
+
+ #change retrieve list to save space
+ retrieve_list = ['out.xml', 'out.error', 'usage.json']
+ node = generate_calc_job_node(entry_point_calc_job,
+ fixture_localhost,
+ name,
+ inputs,
+ store=True,
+ retrieve_list=retrieve_list)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_FLEUR_CALC_FAILED.status
+
+ assert 'output_parameters' not in results
+ assert 'output_params_complex' not in results
+ assert 'relax_parameters' not in results
+ assert 'error_params' not in results
+
+
+def clean_outdict_for_reg_dump(outdict):
+ """
+ Apparently the regression dumper has problems with
+ ' ', '0.33', 'fleur 31', dates
+ we remove these keys.
+ """
+ outdict.pop('creator_target_structure', None)
+ outdict.pop('creator_name', None)
+ outdict.pop('creator_target_architecture', None)
+ outdict.pop('title', None)
+ outdict.pop('output_file_version', None)
+ outdict.pop('start_date', None)
+ outdict.pop('end_date', None)
+ outdict.pop('relax_atomtype_info', None)
+
+ return outdict
diff --git a/tests/parsers/test_fleur_parser/test_fleur_parser_MT_overlap_erroroutput.yml b/tests/parsers/test_fleur_parser/test_fleur_parser_MT_overlap_erroroutput.yml
new file mode 100644
index 000000000..52ca0bdcf
--- /dev/null
+++ b/tests/parsers/test_fleur_parser/test_fleur_parser_MT_overlap_erroroutput.yml
@@ -0,0 +1,8 @@
+error_params:
+ description: This output node contains informationabout FLEUR error
+ error_name: MT_OVERLAP_RELAX
+ iteration_number: 3
+ overlaping_value: '6.8200E-03'
+ overlapped_indices:
+ - '2'
+ - '1'
diff --git a/tests/parsers/test_fleur_parser/test_fleur_parser_default_full.yml b/tests/parsers/test_fleur_parser/test_fleur_parser_default_full.yml
new file mode 100644
index 000000000..d68282aba
--- /dev/null
+++ b/tests/parsers/test_fleur_parser/test_fleur_parser_default_full.yml
@@ -0,0 +1,35 @@
+output_parameters:
+ bandgap: 0.85561712
+ bandgap_units: eV
+ charge_den_xc_den_integral: -41.74447706
+ charge_density: 3.29535e-05
+ density_convergence_units: me/bohr^3
+ energy: -15784.562940686706
+ energy_core_electrons: -316.8117176949
+ energy_hartree: -580.0719889092
+ energy_hartree_units: Htr
+ energy_units: eV
+ energy_valence_electrons: 0.1710194344
+ fermi_energy: 0.2022322894
+ fermi_energy_units: Htr
+ force_largest: -0.0
+ kmax: 3.5
+ number_of_atom_types: 1
+ number_of_atoms: 2
+ number_of_iterations: 11
+ number_of_iterations_total: 11
+ number_of_kpoints: 60
+ number_of_species: 1
+ number_of_spin_components: 1
+ number_of_symmetries: 48
+ parser_info: AiiDA Fleur Parser v0.3.2
+ parser_warnings: []
+ sum_of_eigenvalues: -316.6406982605
+ unparsed: []
+ walltime: 4
+ walltime_units: seconds
+ warnings:
+ debug: {}
+ error: {}
+ info: {}
+ warning: {}
diff --git a/tests/parsers/test_fleur_parser/test_fleur_parser_relax.yml b/tests/parsers/test_fleur_parser/test_fleur_parser_relax.yml
new file mode 100644
index 000000000..5cc7e75c9
--- /dev/null
+++ b/tests/parsers/test_fleur_parser/test_fleur_parser_relax.yml
@@ -0,0 +1,82 @@
+output_parameters:
+ abspos_x_type1: 0.0
+ abspos_y_type1: 0.0
+ abspos_z_type1: -0.741699
+ bandgap: 10.6740023301
+ bandgap_units: eV
+ charge_den_xc_den_integral: -0.6753699578
+ density_convergence_units: null
+ energy: -31.649357888579065
+ energy_core_electrons: 0.0
+ energy_hartree: -1.1630924497
+ energy_hartree_units: Htr
+ energy_units: eV
+ energy_valence_electrons: -0.747242106
+ fermi_energy: -0.373621053
+ fermi_energy_units: Htr
+ film: 'True'
+ force_largest: 0.02082935
+ force_units: Htr/bohr
+ force_x_type1: 0.0
+ force_y_type1: 0.0
+ force_z_type1: 0.02082935
+ kmax: 5.0
+ number_of_atom_types: 1
+ number_of_atoms: 2
+ number_of_iterations: 42
+ number_of_iterations_total: 142
+ number_of_kpoints: 1
+ number_of_species: 1
+ number_of_spin_components: 1
+ number_of_symmetries: 16
+ parser_info: AiiDA Fleur Parser v0.3.2
+ parser_warnings:
+ - 'Can not get attributename: "units" from node "[]", because node is not an element
+ of etree.'
+ relax_atom_positions:
+ - - 0.0
+ - 0.0
+ - -0.741699171
+ - - 0.0
+ - 0.0
+ - 0.741699171
+ relax_brav_vectors:
+ - - 28.345891875
+ - 0.0
+ - 0.0
+ - - 0.0
+ - 28.345891875
+ - 0.0
+ - - 0.0
+ - 0.0
+ - 4.63
+ sum_of_eigenvalues: -0.747242106
+ unparsed: []
+ walltime: 10290
+ walltime_units: seconds
+ warnings:
+ debug: {}
+ error: {}
+ info: {}
+ warning: {}
+relax_parameters:
+ displacements:
+ - - 0.0
+ - 0.0
+ - 0.0246059526
+ energies:
+ - -1.1623986264
+ - -1.1630924497
+ posforces:
+ - - - 0.0
+ - 0.0
+ - -0.75589045
+ - 0.0
+ - 0.0
+ - 0.028382558
+ - - - 0.0
+ - 0.0
+ - -0.741699171
+ - 0.0
+ - 0.0
+ - 0.0208293472
diff --git a/tests/parsers/test_inpgen_parser.py b/tests/parsers/test_inpgen_parser.py
index 5c682871c..d70ab37ff 100644
--- a/tests/parsers/test_inpgen_parser.py
+++ b/tests/parsers/test_inpgen_parser.py
@@ -1,5 +1,117 @@
# -*- coding: utf-8 -*-
-# test all routines used by inpgen parser
+''' Contains tests for the inpgen parser and its routines. '''
# TODO: implement all
# test the full parser itself.
+
+from aiida.common import AttributeDict
+from aiida import orm
+
+
+def test_inpgen_parser_default(fixture_localhost, generate_parser, generate_calc_job_node, generate_structure,
+ data_regression):
+ """
+ Default inpgen parser test of a successful inpgen calculation.
+ Checks via data regression if attributes of fleurinp are the same
+ """
+
+ name = 'default'
+ entry_point_calc_job = 'fleur.inpgen'
+ entry_point_parser = 'fleur.fleurinpgenparser'
+
+ inputs = AttributeDict({'structure': generate_structure(), 'metadata': {}})
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_finished_ok, calcfunction.exit_message
+ assert not orm.Log.objects.get_logs_for(node), [log.message for log in orm.Log.objects.get_logs_for(node)]
+ assert 'fleurinpData' in results
+
+ data_regression.check({
+ 'fleurinpData': results['fleurinpData'].inp_dict,
+ })
+
+
+def test_inpgen_parser_no_inpxml(fixture_localhost, generate_parser, generate_calc_job_node, generate_structure):
+ """
+ Default inpgen parser test of a failed inpgen calculation, inp.xml file missing.
+ """
+
+ name = 'no_inpxml'
+ entry_point_calc_job = 'fleur.inpgen'
+ entry_point_parser = 'fleur.fleurinpgenparser'
+
+ inputs = AttributeDict({'structure': generate_structure(), 'metadata': {}})
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_NO_INPXML.status
+ assert 'fleurinpData' not in results
+
+
+def test_inpgen_parser_no_other_files(fixture_localhost, generate_parser, generate_calc_job_node, generate_structure):
+ """
+ Default inpgen parser test of a failed inpgen calculation, where files are missing.
+ """
+
+ name = 'no_otherfiles'
+ entry_point_calc_job = 'fleur.inpgen'
+ entry_point_parser = 'fleur.fleurinpgenparser'
+
+ inputs = AttributeDict({'structure': generate_structure(), 'metadata': {}})
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_MISSING_RETRIEVED_FILES.status
+ assert 'fleurinpData' not in results
+
+
+def test_inpgen_parser_broken_inpxml(fixture_localhost, generate_parser, generate_calc_job_node, generate_structure):
+ """
+ Default inpgen parser test of a failed inpgen calculation with broken xml.
+ """
+
+ name = 'broken_inpxml'
+ entry_point_calc_job = 'fleur.inpgen'
+ entry_point_parser = 'fleur.fleurinpgenparser'
+
+ inputs = AttributeDict({'structure': generate_structure(), 'metadata': {}})
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_FLEURINPDATA_INPUT_NOT_VALID.status
+ assert 'fleurinpData' not in results
+
+
+def test_inpgen_parser_nonvalid_inpxml(fixture_localhost, generate_parser, generate_calc_job_node, generate_structure):
+ """
+ Default inpgen parser test of a failed inpgen calculation with non valid inpmxl.
+ """
+
+ name = 'novalid_inpxml'
+ entry_point_calc_job = 'fleur.inpgen'
+ entry_point_parser = 'fleur.fleurinpgenparser'
+
+ inputs = AttributeDict({'structure': generate_structure(), 'metadata': {}})
+ node = generate_calc_job_node(entry_point_calc_job, fixture_localhost, name, inputs, store=True)
+ parser = generate_parser(entry_point_parser)
+ results, calcfunction = parser.parse_from_node(node, store_provenance=False)
+
+ assert calcfunction.is_finished, calcfunction.exception
+ assert calcfunction.is_failed, calcfunction.exit_status
+ assert calcfunction.exit_status == node.process_class.exit_codes.ERROR_FLEURINPDATA_INPUT_NOT_VALID.status
+ assert 'fleurinpData' not in results
+
+
+# TODO test multi files, enpara, kpts, relax.xml nnmpmat ...
diff --git a/tests/parsers/test_inpgen_parser/test_inpgen_parser_default.yml b/tests/parsers/test_inpgen_parser/test_inpgen_parser_default.yml
new file mode 100644
index 000000000..45b4bbfde
--- /dev/null
+++ b/tests/parsers/test_inpgen_parser/test_inpgen_parser_default.yml
@@ -0,0 +1,338 @@
+fleurinpData:
+ atomGroups:
+ atomGroup:
+ - force:
+ calculate: true
+ relaxXYZ: TTT
+ nocoParams:
+ alpha: 0.0
+ b_cons_x: '.00000000'
+ b_cons_y: '.00000000'
+ beta: '.00000000'
+ l_relax: F
+ relPos:
+ - .0000000000 .0000000000 .0000000000
+ species: W-1
+ atomSpecies:
+ species:
+ - atomicCutoffs:
+ lmax: 12
+ lnonsphr: 6
+ atomicNumber: 74
+ coreStates: 16
+ electronConfig:
+ coreConfig: '[Kr] (4d3/2) (4d5/2) (4f5/2) (4f7/2)'
+ stateOccupation:
+ - spinDown: '.00000000'
+ spinUp: '2.00000000'
+ state: (5d3/2)
+ - spinDown: '.00000000'
+ spinUp: '2.00000000'
+ state: (5d5/2)
+ valenceConfig: (5s1/2) (5p1/2) (5p3/2) (6s1/2) (5d3/2) (5d5/2)
+ element: W
+ energyParameters:
+ d: 5
+ f: 5
+ p: 6
+ s: 6
+ flipSpin: true
+ lo:
+ - eDeriv: 0
+ l: 0
+ n: 5
+ type: SCLO
+ - eDeriv: 0
+ l: 1
+ n: 5
+ type: SCLO
+ magMom: 0.0
+ mtSphere:
+ gridPoints: 981
+ logIncrement: 0.016
+ radius: 2.1
+ name: W-1
+ prodBasis:
+ lcutm: '4'
+ lcutwf: '11'
+ select: 4 0 4 2
+ calculationSetup:
+ bzIntegration:
+ altKPointSet:
+ kPointCount:
+ count: 240
+ gamma: false
+ purpose: bands
+ fermiSmearingEnergy: 0.0005
+ kPointList:
+ count: 4
+ kPoint:
+ - -0.000000 0.333333 0.333333
+ - -0.333333 0.333333 0.333333
+ - -0.000000 0.000000 0.333333
+ - 0.000000 0.000000 0.000000
+ posScale: '1.00000000'
+ weightScale: '1.00000000'
+ mode: hist
+ valenceElectrons: 14.0
+ coreElectrons:
+ coretail_lmax: '0'
+ ctail: true
+ frcor: false
+ kcrel: 0
+ cutoffs:
+ Gmax: 15.0
+ GmaxXC: 12.5
+ Kmax: 5.0
+ numbands: 0
+ energyParameterLimits:
+ ellow: -1.8
+ elup: 1.0
+ expertModes:
+ gw: 0
+ secvar: false
+ geometryOptimization:
+ epsdisp: 1.0e-05
+ epsforce: 1.0e-05
+ forcealpha: 1.0
+ forcemix: BFGS
+ l_f: false
+ ldaU:
+ - l_linMix: false
+ mixParam: 0.05
+ spinf: 1.0
+ magnetism:
+ jspins: 1
+ l_noco: false
+ lflip: false
+ swsp: false
+ nocoParams:
+ l_constr: F
+ l_mperp: F
+ l_ss: false
+ mix_b: '.00000000'
+ qss: .0000000000 .0000000000 .0000000000
+ prodBasis:
+ bands: '0'
+ ewaldlambda: '3'
+ gcutm: '3.40000000'
+ lexp: '16'
+ tolerance: '.00010000'
+ scfLoop:
+ alpha: 0.05
+ imix: Anderson
+ itmax: 15
+ maxIterBroyd: 99
+ minDistance: 1.0e-05
+ precondParam: '0.0'
+ spinf: 2.0
+ soc:
+ l_soc: false
+ phi: 0.0
+ spav: false
+ theta: 0.0
+ cell:
+ bulkLattice:
+ bravaisMatrix:
+ row-1: -3.013812060000000 3.013812060000000 3.013812060000000
+ row-2: 3.013812060000000 -3.013812060000000 3.013812060000000
+ row-3: 3.013812060000000 3.013812060000000 -3.013812060000000
+ latnam: any
+ scale: 1.0
+ symmetryOperations:
+ symOp:
+ - row-1: 1 0 0 .0000000000
+ row-2: 0 1 0 .0000000000
+ row-3: 0 0 1 .0000000000
+ - row-1: -1 0 0 .0000000000
+ row-2: -1 1 0 .0000000000
+ row-3: -1 0 1 .0000000000
+ - row-1: 1 -1 0 .0000000000
+ row-2: 0 -1 0 .0000000000
+ row-3: 0 -1 1 .0000000000
+ - row-1: 0 -1 0 .0000000000
+ row-2: 1 -1 0 .0000000000
+ row-3: 0 -1 1 .0000000000
+ - row-1: -1 1 0 .0000000000
+ row-2: -1 0 0 .0000000000
+ row-3: -1 0 1 .0000000000
+ - row-1: 0 1 0 .0000000000
+ row-2: 1 0 0 .0000000000
+ row-3: 0 0 1 .0000000000
+ - row-1: 1 0 -1 .0000000000
+ row-2: 0 1 -1 .0000000000
+ row-3: 0 0 -1 .0000000000
+ - row-1: 0 0 -1 .0000000000
+ row-2: 0 1 -1 .0000000000
+ row-3: 1 0 -1 .0000000000
+ - row-1: 0 1 -1 .0000000000
+ row-2: 1 0 -1 .0000000000
+ row-3: 0 0 -1 .0000000000
+ - row-1: 0 1 -1 .0000000000
+ row-2: 0 0 -1 .0000000000
+ row-3: 1 0 -1 .0000000000
+ - row-1: 1 0 -1 .0000000000
+ row-2: 0 0 -1 .0000000000
+ row-3: 0 1 -1 .0000000000
+ - row-1: 0 0 -1 .0000000000
+ row-2: 1 0 -1 .0000000000
+ row-3: 0 1 -1 .0000000000
+ - row-1: -1 0 0 .0000000000
+ row-2: 0 -1 0 .0000000000
+ row-3: 0 0 -1 .0000000000
+ - row-1: 1 0 0 .0000000000
+ row-2: 1 -1 0 .0000000000
+ row-3: 1 0 -1 .0000000000
+ - row-1: 0 -1 0 .0000000000
+ row-2: -1 0 0 .0000000000
+ row-3: 0 0 -1 .0000000000
+ - row-1: 1 -1 0 .0000000000
+ row-2: 1 0 0 .0000000000
+ row-3: 1 0 -1 .0000000000
+ - row-1: 0 1 0 .0000000000
+ row-2: -1 1 0 .0000000000
+ row-3: 0 1 -1 .0000000000
+ - row-1: -1 1 0 .0000000000
+ row-2: 0 1 0 .0000000000
+ row-3: 0 1 -1 .0000000000
+ - row-1: -1 0 0 .0000000000
+ row-2: 0 0 -1 .0000000000
+ row-3: 0 -1 0 .0000000000
+ - row-1: 1 0 0 .0000000000
+ row-2: 1 0 -1 .0000000000
+ row-3: 1 -1 0 .0000000000
+ - row-1: 0 -1 0 .0000000000
+ row-2: 0 0 -1 .0000000000
+ row-3: -1 0 0 .0000000000
+ - row-1: 1 -1 0 .0000000000
+ row-2: 1 0 -1 .0000000000
+ row-3: 1 0 0 .0000000000
+ - row-1: 0 1 0 .0000000000
+ row-2: 0 1 -1 .0000000000
+ row-3: -1 1 0 .0000000000
+ - row-1: -1 1 0 .0000000000
+ row-2: 0 1 -1 .0000000000
+ row-3: 0 1 0 .0000000000
+ - row-1: 0 0 -1 .0000000000
+ row-2: -1 0 0 .0000000000
+ row-3: 0 -1 0 .0000000000
+ - row-1: 1 0 -1 .0000000000
+ row-2: 1 0 0 .0000000000
+ row-3: 1 -1 0 .0000000000
+ - row-1: 0 0 -1 .0000000000
+ row-2: 0 -1 0 .0000000000
+ row-3: -1 0 0 .0000000000
+ - row-1: 1 0 -1 .0000000000
+ row-2: 1 -1 0 .0000000000
+ row-3: 1 0 0 .0000000000
+ - row-1: 0 1 -1 .0000000000
+ row-2: 0 1 0 .0000000000
+ row-3: -1 1 0 .0000000000
+ - row-1: 0 1 -1 .0000000000
+ row-2: -1 1 0 .0000000000
+ row-3: 0 1 0 .0000000000
+ - row-1: -1 0 1 .0000000000
+ row-2: -1 1 0 .0000000000
+ row-3: -1 0 0 .0000000000
+ - row-1: 0 0 1 .0000000000
+ row-2: 0 1 0 .0000000000
+ row-3: 1 0 0 .0000000000
+ - row-1: 0 -1 1 .0000000000
+ row-2: 1 -1 0 .0000000000
+ row-3: 0 -1 0 .0000000000
+ - row-1: 0 -1 1 .0000000000
+ row-2: 0 -1 0 .0000000000
+ row-3: 1 -1 0 .0000000000
+ - row-1: -1 0 1 .0000000000
+ row-2: -1 0 0 .0000000000
+ row-3: -1 1 0 .0000000000
+ - row-1: 0 0 1 .0000000000
+ row-2: 1 0 0 .0000000000
+ row-3: 0 1 0 .0000000000
+ - row-1: 1 -1 0 .0000000000
+ row-2: 0 -1 1 .0000000000
+ row-3: 0 -1 0 .0000000000
+ - row-1: 0 -1 0 .0000000000
+ row-2: 0 -1 1 .0000000000
+ row-3: 1 -1 0 .0000000000
+ - row-1: -1 1 0 .0000000000
+ row-2: -1 0 1 .0000000000
+ row-3: -1 0 0 .0000000000
+ - row-1: 0 1 0 .0000000000
+ row-2: 0 0 1 .0000000000
+ row-3: 1 0 0 .0000000000
+ - row-1: 1 0 0 .0000000000
+ row-2: 0 0 1 .0000000000
+ row-3: 0 1 0 .0000000000
+ - row-1: -1 0 0 .0000000000
+ row-2: -1 0 1 .0000000000
+ row-3: -1 1 0 .0000000000
+ - row-1: 0 0 1 .0000000000
+ row-2: -1 0 1 .0000000000
+ row-3: 0 -1 1 .0000000000
+ - row-1: -1 0 1 .0000000000
+ row-2: 0 0 1 .0000000000
+ row-3: 0 -1 1 .0000000000
+ - row-1: 0 0 1 .0000000000
+ row-2: 0 -1 1 .0000000000
+ row-3: -1 0 1 .0000000000
+ - row-1: -1 0 1 .0000000000
+ row-2: 0 -1 1 .0000000000
+ row-3: 0 0 1 .0000000000
+ - row-1: 0 -1 1 .0000000000
+ row-2: 0 0 1 .0000000000
+ row-3: -1 0 1 .0000000000
+ - row-1: 0 -1 1 .0000000000
+ row-2: -1 0 1 .0000000000
+ row-3: 0 0 1 .0000000000
+ comment: A Fleur input generator calculation with aiida
+ fleurInputVersion: '0.31'
+ output:
+ band: false
+ chargeDensitySlicing:
+ maxEigenval: 0.0
+ minEigenval: 0.0
+ nnne: 0
+ numkpt: 0
+ pallst: false
+ checks:
+ cdinf: false
+ vchk: false
+ densityOfStates:
+ maxEnergy: 0.5
+ minEnergy: -0.5
+ ndir: 0
+ sigma: 0.015
+ dos: false
+ magneticCircularDichroism:
+ energyLo: '-10.00000000'
+ energyUp: '.00000000'
+ mcd: F
+ plotting:
+ iplot: 0
+ plplot: false
+ score: false
+ slice: false
+ specialOutput:
+ bmt: false
+ eonly: false
+ unfoldingBand:
+ supercellX: '1'
+ supercellY: '1'
+ supercellZ: '1'
+ unfoldBand: F
+ vacdos: false
+ vacuumDOS:
+ integ: false
+ layers: 0
+ locx1: 0.0
+ locx2: 0.0
+ locy1: 0.0
+ locy2: 0.0
+ nstars: 0
+ nstm: 0
+ star: false
+ tworkf: 0.0
+ xcFunctional:
+ name: pbe
+ relativisticCorrections: false
diff --git a/tests/pylint.svg b/tests/pylint.svg
deleted file mode 100644
index 61836ac08..000000000
--- a/tests/pylint.svg
+++ /dev/null
@@ -1,20 +0,0 @@
-
diff --git a/tests/run_all_cov.sh b/tests/run_all_cov.sh
index 59dcd37f3..9f40c5792 100755
--- a/tests/run_all_cov.sh
+++ b/tests/run_all_cov.sh
@@ -3,7 +3,7 @@ export AIIDA_PATH='.';
mkdir -p '.aiida';
#pytest -sv
#pytest -v
-pytest --cov-report=term-missing:skip-covered --cov=aiida_fleur
+pytest --cov-report=xml --cov=aiida_fleur
#pytest --cov-report=html --cov=aiida_fleur
#pytest --cov-report=html --cov=aiida_fleur -vv -rXxs -x
diff --git a/tests/run_all_cov_show.sh b/tests/run_all_cov_show.sh
new file mode 100755
index 000000000..59dcd37f3
--- /dev/null
+++ b/tests/run_all_cov_show.sh
@@ -0,0 +1,14 @@
+#!/usr/bin/env sh
+export AIIDA_PATH='.';
+mkdir -p '.aiida';
+#pytest -sv
+#pytest -v
+pytest --cov-report=term-missing:skip-covered --cov=aiida_fleur
+#pytest --cov-report=html --cov=aiida_fleur
+#pytest --cov-report=html --cov=aiida_fleur -vv -rXxs -x
+
+# to create badge (requires coverage-badge)
+#coverage-badge -o coverage.svg
+
+# pylint (for shield create, by hand, or write script to write total into svg)
+# pylint ../../aiida_fleur/ > outlint
diff --git a/tests/test_entrypoints.py b/tests/test_entrypoints.py
index 763a7ec30..00ceae9c3 100644
--- a/tests/test_entrypoints.py
+++ b/tests/test_entrypoints.py
@@ -75,13 +75,6 @@ def test_fleur_dos_wc_entry_point(self):
workflow = WorkflowFactory('fleur.dos')
assert workflow == fleur_dos_wc
- def test_fleur_band_wc_entry_point(self):
- from aiida.plugins import WorkflowFactory
- from aiida_fleur.workflows.band import FleurBandWorkChain
-
- workflow = WorkflowFactory('fleur.band')
- assert workflow == FleurBandWorkChain
-
def test_fleur_banddos_wc_entry_point(self):
from aiida.plugins import WorkflowFactory
from aiida_fleur.workflows.banddos import FleurBandDosWorkChain
diff --git a/tests/test_workflows_builder_init.py b/tests/test_workflows_builder_init.py
index 5e1cc7e46..15252f411 100644
--- a/tests/test_workflows_builder_init.py
+++ b/tests/test_workflows_builder_init.py
@@ -55,22 +55,6 @@ def test_fleur_dos_wc_init(self):
builder = fleur_dos_wc.get_builder()
- def test_fleur_band_wc_init(self):
- """
- Test the interface of the band workchain
- """
- from aiida_fleur.workflows.band import FleurBandWorkChain
-
- builder = FleurBandWorkChain.get_builder()
-
- # def test_fleur_band2_wc_init(self):
- # """
- # Test the interface of the band2 workchain
- # """
- # from aiida_fleur.workflows.band2 import fleur_band2_wc
- #
- # builder = fleur_band2_wc.get_builder()
-
def test_fleur_corehole_wc_init(self):
"""
Test the interface of the corehole workchain
@@ -87,14 +71,6 @@ def test_fleur_initial_cls_wc_init(self):
builder = fleur_initial_cls_wc.get_builder()
- def test_fleur_delta_wc_init(self):
- """
- Test the interface of the delta workchain
- """
- from aiida_fleur.workflows.delta import fleur_delta_wc
-
- builder = fleur_delta_wc.get_builder()
-
def test_fleur_relax_wc_init(self):
"""
Test the interface of the relax workchain
diff --git a/tests/tools/test_StructureData_util.py b/tests/tools/test_StructureData_util.py
index 0542e510c..a6ceaadeb 100644
--- a/tests/tools/test_StructureData_util.py
+++ b/tests/tools/test_StructureData_util.py
@@ -16,6 +16,7 @@
def test_is_structure(generate_structure):
+ """Test if is structure can differentiate between structures, identifiers and else"""
from aiida_fleur.tools.StructureData_util import is_structure
from aiida.orm import Dict
@@ -34,6 +35,7 @@ def test_is_structure(generate_structure):
def test_is_primitive(generate_structure):
+ """Test if is_primitive test can distinguish between a primitive and non primitive structure"""
from aiida_fleur.tools.StructureData_util import is_primitive
structure = generate_structure()
structure.store()
@@ -51,23 +53,41 @@ def test_is_primitive(generate_structure):
def test_rescale_nowf(generate_structure):
+ """Test to rescale some structure """
from aiida_fleur.tools.StructureData_util import rescale_nowf
+ from aiida_fleur.tools.StructureData_util import rescale
+ from aiida.orm import Dict, Float
+
structure = generate_structure()
old_cell = np.array(structure.cell)
rescaled = rescale_nowf(structure, 1.05)
+ rescaled2 = rescale(structure, Float(1.05))
rescaled_cell = np.array(rescaled.cell)
+ rescaled_cell2 = np.array(rescaled2.cell)
assert (rescaled_cell == 1.05**(1 / 3.) * old_cell).all()
+ #assert (np.round(rescaled_cell2, 13) == 1.05**(1 / 3.) * old_cell).all()
+ # This does not work, seems to check if it is the same object, not if values are the same
+ # The precision between these functions is strangely different
+ assert list(np.round(rescaled_cell[0], 13)) == list(rescaled_cell2[0])
+ assert list(np.round(rescaled_cell[1], 13)) == list(rescaled_cell2[1])
+ assert list(np.round(rescaled_cell[2], 13)) == list(rescaled_cell2[2])
positions_old = [x.position for x in structure.sites]
positions_rescaled = [x.position for x in rescaled.sites]
for position in positions_old:
assert tuple(pos * 1.05**(1 / 3.) for pos in position) in positions_rescaled
+ no_struc = Dict(dict={})
+ no_rescaled = rescale_nowf(no_struc, 1.05)
+ assert no_rescaled is None
+
def test_supercell(generate_structure):
+ """Test to create a super cell"""
from aiida_fleur.tools.StructureData_util import supercell
+ from aiida_fleur.tools.StructureData_util import supercell_ncf
from aiida.orm import Int
from itertools import product
@@ -89,6 +109,10 @@ def test_supercell(generate_structure):
z * np.array(structure.cell[2]))
assert test_pos in positions_rescaled
+ no_struc = Int(1)
+ no_supercell = supercell_ncf(no_struc, 2, 3, 4)
+ assert no_supercell is None
+
def test_abs_to_rel(generate_structure):
from aiida_fleur.tools.StructureData_util import abs_to_rel
@@ -113,6 +137,7 @@ def test_abs_to_rel_f(generate_film_structure):
def test_rel_to_abs(generate_structure):
+ """Test if rel_to_abs for bulk function scales coordinates right"""
from aiida_fleur.tools.StructureData_util import rel_to_abs
structure = generate_structure()
@@ -124,6 +149,7 @@ def test_rel_to_abs(generate_structure):
def test_rel_to_abs_f(generate_film_structure):
+ """Test if rel_to_abs film function scales coordinates right"""
from aiida_fleur.tools.StructureData_util import rel_to_abs_f
structure = generate_film_structure()
@@ -134,11 +160,10 @@ def test_rel_to_abs_f(generate_film_structure):
assert not rel_to_abs_f([1], cell)
-def test_break_symmetry_wf(generate_film_structure):
- """
- Check if it does not crash and able to destroy all symmetries
- """
+def test_break_symmetry_wf_film_structure_only(generate_film_structure):
+ """Check if it does not crash and able to destroy all symmetries"""
from aiida_fleur.tools.StructureData_util import break_symmetry_wf, supercell_ncf
+ from aiida_fleur.tools.StructureData_util import break_symmetry
from aiida.orm import Dict
structure = generate_film_structure()
@@ -150,12 +175,542 @@ def test_break_symmetry_wf(generate_film_structure):
)
structure_broken = out['new_structure']
kind_names = [x.kind_name for x in structure_broken.sites]
+ kind_names_should = ['Fe1', 'Fe2', 'Fe3', 'Fe4', 'Pt1', 'Pt2', 'Pt3', 'Pt4', 'Pt5', 'Pt6', 'Pt7', 'Pt8']
+ for kind_name in kind_names_should:
+ assert kind_name in kind_names
+ assert len(set(kind_names)) == len(kind_names_should)
+
+ struc_b_fe, para_new_fe = break_symmetry(structure, atoms=['Fe'])
+ kind_names = [x.kind_name for x in struc_b_fe.sites]
+ kind_names_should = ['Fe1', 'Fe2', 'Fe3', 'Fe4', 'Pt']
+ for kind_name in kind_names_should:
+ assert kind_name in kind_names
+ assert len(set(kind_names)) == len(kind_names_should)
- for kind_name in ['Fe1', 'Fe1', 'Fe1', 'Fe1', 'Pt1', 'Pt2', 'Pt3', 'Pt4', 'Pt5', 'Pt6', 'Pt7', 'Pt8']:
+ struc_b_pt, para_new_pt = break_symmetry(structure, atoms=['Pt'])
+ kind_names = [x.kind_name for x in struc_b_pt.sites]
+ kind_names_should = ['Fe', 'Pt1', 'Pt2', 'Pt3', 'Pt4', 'Pt5', 'Pt6', 'Pt7', 'Pt8']
+ for kind_name in kind_names_should:
assert kind_name in kind_names
+ assert len(set(kind_names)) == len(kind_names_should)
+
+ struc_b_site, para_new_site = break_symmetry(structure, atoms=[], site=[0, 1])
+ kind_names = [x.kind_name for x in struc_b_site.sites]
+ kind_names_should = ['Fe', 'Fe1', 'Fe2', 'Pt']
+ for kind_name in kind_names_should:
+ assert kind_name in kind_names
+ assert len(set(kind_names)) == len(kind_names_should)
+
+ pos = [structure.sites[0].position, structure.sites[1].position]
+
+ struc_b_pos, para_new_pos = break_symmetry(structure, atoms=[], pos=pos)
+ kind_names = [x.kind_name for x in struc_b_pos.sites]
+ kind_names_should = ['Fe', 'Fe1', 'Fe2', 'Pt']
+ for kind_name in kind_names_should:
+ assert kind_name in kind_names
+ assert len(set(kind_names)) == len(kind_names_should)
+
+
+def test_break_symmetry_corhole(generate_structure):
+ """Test if what the corehole workflow does works"""
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+ from aiida import orm
+
+ structure = generate_structure()
+ sites = structure.sites
+ pos = sites[0].position
+ kind_name = sites[0].kind_name
+ para = orm.Dict(dict={
+ 'atom': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+ new_kinds_names = {'Si': [kind_name + '_corehole1']}
+ inputs = dict(structure=structure,
+ atoms=[],
+ site=[],
+ pos=[(pos[0], pos[1], pos[2])],
+ new_kinds_names=new_kinds_names)
+ if para is not None:
+ inputs['parameterdata'] = para
+ new_struc, new_para = break_symmetry(**inputs)
+
+ #print(new_para.get_dict())
+ kind_names = ['Si_corehole1', 'Si']
+ for i, site in enumerate(new_struc.sites):
+ assert site.kind_name == kind_names[i]
+
+ # Test if the kind name was set to the atom lists
+ should = {
+ 'atom1': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom2': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6,
+ 'id': '14.1',
+ 'name': 'Si_corehole1'
+ }
+ }
+ assert new_para.get_dict() == should
+
+
+def test_break_symmetry_film_parameters_only_simple(generate_film_structure):
+ """Test if these break symmetry operation adjusted the parameter data right.
+ This basicly tests
+ from aiida_fleur.tools.StructureData_util import adjust_calc_para_to_structure
+ for a separate test we would have to generate these structures again
+ """
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+ from aiida.orm import Dict
+
+ structure = generate_film_structure()
+ para = Dict(
+ dict={
+ 'atom': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom1': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+
+ structure_broken, para_out = break_symmetry(structure, parameterdata=para)
+ should1 = {
+ 'atom1': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom2': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom3': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1,
+ 'id': '26.1'
+ },
+ 'atom4': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1,
+ 'id': '78.1'
+ },
+ 'atom5': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1,
+ 'id': '78.2'
+ }
+ }
+ assert para_out.get_dict() == should1
+
+ # breaking again should not change something
+ structure_broken, para_out = break_symmetry(structure_broken, parameterdata=para_out)
+ assert para_out.get_dict() == should1
+
+ should2 = {
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom1': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1,
+ 'id': '26.1'
+ },
+ 'atom2': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1,
+ 'id': '78.1'
+ },
+ 'atom3': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1,
+ 'id': '78.2'
+ }
+ }
+ structure_broken, para_out = break_symmetry(structure_broken, parameterdata=para_out, add_atom_base_lists=False)
+ print(para_out.get_dict())
+ assert para_out.get_dict() == should2
+
+ struc_b_fe, para_new_fe = break_symmetry(structure, atoms=['Fe'], parameterdata=para)
+
+ should3 = {
+ 'atom1': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom2': {
+ 'element': 'Pt',
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom3': {
+ 'element': 'Fe',
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1,
+ 'id': '26.1'
+ }
+ }
+ assert para_new_fe.get_dict() == should3
+
+
+def test_break_symmetry_film_parameters_only_complex(generate_film_structure):
+ """Test if these break symmetry operation adjusted the complex parameter data right.
+ This basicly tests
+ from aiida_fleur.tools.StructureData_util import adjust_calc_para_to_structure
+ for a separate test we would have to generate these structures again
+ """
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+ from aiida.orm import Dict
+
+ structure = generate_film_structure()
+ para = Dict(
+ dict={
+ 'atom': {
+ 'element': 'Fe',
+ 'id': 26.1,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom1': {
+ 'element': 'Pt',
+ 'id': 78.1,
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+
+ structure_broken, para_out = break_symmetry(structure, parameterdata=para)
+ struc_b_fe, para_new_fe = break_symmetry(structure, atoms=['Fe'], parameterdata=para)
+
+ should1 = {
+ 'atom1': {
+ 'element': 'Fe',
+ 'id': '26.1',
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom2': {
+ 'element': 'Pt',
+ 'id': '78.1',
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'atom3': {
+ 'element': 'Pt',
+ 'id': '78.2',
+ 'rmt': 2.2,
+ 'bmu': 1
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ }
+
+ assert para_out.get_dict() == should1
+
+ should2 = {'atom1': {'bmu': -1, 'element': 'Fe', 'id': '26.1', 'rmt': 2.1}, 'comp': {'kmax': 5.0}}
+ assert para_new_fe.get_dict() == should2
+ # Deletes the other Ids because Pt had an id
+
+
+'''
+
+
+ # old should dict
+ should_out_dict = {
+ 'atom': {
+ 'id': 26,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom1': {
+ 'id': 78.1,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom2': {
+ 'id': 78.2,
+ 'rmt': 2.2,
+ 'bmu': 1
+ }
+ }
+
+ should_out_dict = {'atom1': {'z': 26, 'rmt': 2.1, 'bmu': -1},
+ 'atom2': {'z': 26, 'rmt': 2.1, 'bmu': -1, 'id': '26.1'},
+ 'atom3': {'z': 26, 'rmt': 2.1, 'bmu': -1, 'id': '26.2'},
+ 'atom4': {'z': 26, 'rmt': 2.1, 'bmu': -1, 'id': '26.3'},
+ 'atom5': {'z': 26, 'rmt': 2.1, 'bmu': -1, 'id': '26.4'}}
+ parameter_data = Dict(
+ dict={
+ 'atom': {
+ 'z': 26,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom1': {
+ 'id': 78.1,
+ 'rmt': 2.1,
+ 'bmu': -1
+ },
+ 'atom2': {
+ 'id': 78.2,
+ 'rmt': 2.2,
+ 'bmu': 1
+ }
+ })
+ out, parameterdata_new = break_symmetry(structure, parameterdata=parameter_data)
+ out_dict = parameterdata_new.get_dict()
+ print(out_dict)
+ assert out_dict == should_out_dict
+'''
+'''
+def test_break_symmetry_bulk(generate_structure):
+ """Check if it does not crash and able to destroy all symmetries"""
+ from aiida_fleur.tools.StructureData_util import break_symmetry, supercell_ncf
+ from aiida.orm import Dict
+
+ structure = generate_structure()
+
+ # Test if break symmetry adjusts parameters right with simple parameters
+
+ parameter_data = Dict(
+ dict={
+ 'atom': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }})
+ structure_broken, parameters1 = break_symmetry(structure, parameterdata=parameter_data)
+
+ print('para1', parameters1.get_dict())
+ should_para1 = {
+ 'atom0': {
+ 'element': 'Si',
+ 'id': 14.1,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'atom1': {
+ 'element': 'Si',
+ 'id': 14.2,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }}
+ assert parameters1.get_dict() == should_para1
+ # Now test if it also adjusts for complex parameters right
+ parameter_data2 = Dict(dict={
+ 'atom1': {
+ 'element': 'Si',
+ 'id': 14.1,
+ 'rmt': 2.2,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'atom2': {
+ 'element': 'Si',
+ 'z' : 14,
+ 'id': 14.2,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 11,
+ 'lnonsph': 6
+ },
+ 'atom': {
+ 'element': 'Si',
+ 'rmt': 2.0,
+ 'jri': 981,
+ 'lmax': 10,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+ structure = supercell_ncf(structure, 2, 1, 1)
+ # Test if break symmetry adjusts the parameter data right.
+ structure_broken, parameters2 = break_symmetry(structure, parameterdata=parameter_data2)
+ kind_names = [x.kind_name for x in structure_broken.sites]
+ for kind_name in ['Si1', 'Si2', 'Si3', 'Si4']:
+ assert kind_name in kind_names
+ print('para2', parameters2.get_dict())
+ para2_should = {
+ 'atom1': {
+ 'element': 'Si',
+ 'id': 14.1,
+ 'rmt': 2.2,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'atom2': {
+ 'element': 'Si',
+ 'z' : 14,
+ 'id': 14.2,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 11,
+ 'lnonsph': 6
+ },
+ 'atom0': {
+ 'element': 'Si',
+ 'id': 14.3,
+ 'rmt': 2.0,
+ 'jri': 981,
+ 'lmax': 10,
+ 'lnonsph': 6
+ },
+ 'atom3': {
+ 'element': 'Si',
+ 'id': 14.4,
+ 'rmt': 2.0,
+ 'jri': 981,
+ 'lmax': 10,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ }
+
+ assert para2_should == parameters2.get_dict()
+ #TODO test break_symmetry with several different elements in parameter and structure
+'''
+
+
+def test_adjust_calc_para_to_structure(generate_structure):
+ """Test intergace of check_structure_para_consistent"""
+ from aiida_fleur.tools.StructureData_util import adjust_calc_para_to_structure
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+ from aiida import orm
+
+ structure = generate_structure()
+
+ parameter_data = orm.Dict(dict={
+ 'atom1': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+ new_para = adjust_calc_para_to_structure(parameter_data, structure)
+ # The parameter data should not be changed
+ assert new_para.get_dict() == parameter_data.get_dict()
+
+ structure_broken, parameters1 = break_symmetry(structure, parameterdata=parameter_data)
+ new_para = adjust_calc_para_to_structure(parameter_data, structure_broken)
+ # The parameter data should be changed and should be the same.
+ assert new_para.get_dict() == parameters1.get_dict()
+
+
+def test_check_structure_para_consistent(generate_structure):
+ """Test intergace of check_structure_para_consistent"""
+ from aiida_fleur.tools.StructureData_util import check_structure_para_consistent
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+ from aiida import orm
+
+ structure = generate_structure()
+
+ parameter_data = orm.Dict(dict={
+ 'atom': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+ assert check_structure_para_consistent(parameter_data, structure)
+
+ structure_broken, parameters1 = break_symmetry(structure, parameterdata=parameter_data)
+ assert check_structure_para_consistent(parameters1, structure_broken)
+ assert check_structure_para_consistent(parameter_data, structure_broken)
+
+ wrong_parameter_data = orm.Dict(dict={
+ 'atom': {
+ 'element': 'P',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+ })
+ assert not check_structure_para_consistent(wrong_parameter_data, structure)
def test_find_equi_atoms(generate_film_structure):
+ """Test if find_equi_atoms functions returns equidistant atoms"""
from aiida_fleur.tools.StructureData_util import find_equi_atoms, supercell_ncf
from numpy import array
@@ -174,6 +729,7 @@ def test_find_equi_atoms(generate_film_structure):
def test_get_spacegroup(generate_film_structure):
+ """Test if get_spacegroup function returns the right spacegroup"""
from aiida_fleur.tools.StructureData_util import get_spacegroup
structure = generate_film_structure()
@@ -181,6 +737,7 @@ def test_get_spacegroup(generate_film_structure):
def test_move_atoms_incell_wf(generate_structure):
+ """Test if move atoms incell functions moves atoms correctly"""
from aiida_fleur.tools.StructureData_util import move_atoms_incell_wf
from aiida.orm import Dict
@@ -198,6 +755,7 @@ def test_move_atoms_incell_wf(generate_structure):
def test_find_primitive_cell_wf(generate_structure):
from aiida_fleur.tools.StructureData_util import find_primitive_cell_wf, supercell_ncf
+ from aiida_fleur.tools.StructureData_util import find_primitive_cells
structure_primitive = generate_structure()
structure = supercell_ncf(structure_primitive, 2, 2, 22)
@@ -207,6 +765,10 @@ def test_find_primitive_cell_wf(generate_structure):
assert all(x in structure_primitive.cell for x in result.cell)
+ resultlist = find_primitive_cells([structure.uuid, structure.uuid])
+ for struc in resultlist:
+ assert all(x in structure_primitive.cell for x in result.cell)
+
def test_center_film_wf(generate_film_structure, generate_structure):
from aiida_fleur.tools.StructureData_util import center_film_wf, move_atoms_incell, center_film
@@ -217,9 +779,9 @@ def test_center_film_wf(generate_film_structure, generate_structure):
structure_film = move_atoms_incell(structure_film, [0.0, 0.0, 1.1242])
centered_film = center_film_wf(structure_film)
- assert [x.position for x in centered_film.sites] == [(0.0, 0.0, -1.2286013142),
- (1.4026317387, 1.9836207751, -0.1740305093),
- (0.0, 0.0, 1.2286013141)]
+ assert [x.position for x in centered_film.sites] == [(0.0, 0.0, -1.2286013139),
+ (1.4026317384, 1.9836207747, -0.1740305094),
+ (0.0, 0.0, 1.2286013138)]
with pytest.raises(TypeError):
center_film(structure_bulk)
@@ -227,20 +789,19 @@ def test_center_film_wf(generate_film_structure, generate_structure):
def test_get_layers(generate_film_structure):
from aiida_fleur.tools.StructureData_util import get_layers
-
+ from aiida_fleur.common.constants import BOHR_A
structure = generate_film_structure()
- assert get_layers(structure) == ([[([0.0, 0.0, -1.054570804781922], 'Fe')],
- [([1.4026317387182539, 1.9836207751336201, 0.0], 'Pt')],
- [([0.0, 0.0, 1.4026318234924429], 'Pt')]], [-1.0545708048, 0.0,
- 1.4026318235], [1, 1, 1])
+ assert get_layers(structure) == ([[([0.0, 0.0, -1.05457080454278], 'Fe')],
+ [([1.402631738400183, 1.9836207746838, 0.0], 'Pt')],
+ [([0.0, 0.0, 1.402631823174372], 'Pt')]], [-1.0545708045, 0.0,
+ 1.4026318232], [1, 1, 1])
- bohr_a_0 = 0.52917721092
- structure.append_atom(position=(1.0, 0., -1.99285 * bohr_a_0), symbols='Fe')
- assert get_layers(structure) == ([[([0.0, 0.0, -1.054570804781922], 'Fe'), ([1.0, 0.0, -1.054570804781922], 'Fe')],
- [([1.4026317387182539, 1.9836207751336201, 0.0], 'Pt')],
- [([0.0, 0.0, 1.4026318234924429], 'Pt')]], [-1.0545708048, 0.0,
- 1.4026318235], [2, 1, 1])
+ structure.append_atom(position=(1.0, 0., -1.99285 * BOHR_A), symbols='Fe')
+ assert get_layers(structure) == ([[([0.0, 0.0, -1.05457080454278], 'Fe'), ([1.0, 0.0, -1.05457080454278], 'Fe')],
+ [([1.402631738400183, 1.9836207746838, 0.0], 'Pt')],
+ [([0.0, 0.0, 1.402631823174372], 'Pt')]], [-1.0545708045, 0.0,
+ 1.4026318232], [2, 1, 1])
create_slab_inputs = [{
@@ -346,6 +907,8 @@ def test_magnetic_slab_from_relaxed(generate_film_structure):
def test_request_average_bond_length(generate_film_structure):
+ """Test interface of request average bond length from mp, requires mp_api_key"""
+ # Todo mock the mp query, since result could change overtime, also that the CI can run this
import os
from aiida_fleur.tools.StructureData_util import request_average_bond_length
@@ -368,6 +931,8 @@ def test_request_average_bond_length(generate_film_structure):
def test_adjust_film_relaxation(generate_film_structure):
+ """Test interface of adjust film relaxation, requires mp_api_key"""
+ # Todo mock the mp query, since result could change overtime, also that the CI can run this
import os
from aiida_fleur.tools.StructureData_util import adjust_film_relaxation
@@ -398,3 +963,35 @@ def test_adjust_film_relaxation(generate_film_structure):
assert result.sites[0].position[2] == -1.1709859694
assert result.sites[1].position[2] == 0.2602185234
assert result.sites[2].position[2] == 1.1709859694
+
+
+def test_create_slap(generate_structure):
+ """Test if create_slap"""
+ from aiida_fleur.tools.StructureData_util import create_slap
+
+ structure = generate_structure()
+ film_struc = create_slap(structure, [1, 1, 1], 2)
+ cell_should = [[3.839589821842953, 0.0, 2.351070692679364e-16],
+ [1.9197949109214756, 3.3251823258281643, 2.351070692679364e-16], [0.0, 0.0, 9.405035885099004]]
+ sites_should = [(3.839589821842953, 2.216788217218776, 3.135011961699669), (0.0, 0.0, 0.0),
+ (1.9197949109214758, 1.1083941086093878, 6.270023923399337)]
+ # since this depends on pymatgen we round here the last digits.
+ assert (np.round(film_struc.cell, 8) == np.round(cell_should, 8)).all()
+ assert (np.round(film_struc.sites[0].position, 8) == np.round(sites_should[0], 8)).all()
+ assert (np.round(film_struc.sites[1].position, 8) == np.round(sites_should[1], 8)).all()
+ assert (np.round(film_struc.sites[2].position, 8) == np.round(sites_should[2], 8)).all()
+
+
+def test_create_all_slabs(generate_structure):
+ """Test if create_all_slabs"""
+ from aiida_fleur.tools.StructureData_util import create_all_slabs
+ from aiida.orm import StructureData
+
+ structure = generate_structure()
+ film_strucs = create_all_slabs(structure, 2, 5)
+
+ assert len(film_strucs.keys()) == 9
+ assert list(film_strucs.keys()) == [(1, 1, 1), (2, 2, 1), (1, 1, 0), (2, 2, -1), (2, 1, 1), (2, 1, -1), (2, 1, -2),
+ (2, 0, -1), (2, -1, -1)]
+ for key, film_struc in film_strucs.items():
+ assert isinstance(film_struc, StructureData)
diff --git a/tests/tools/test_StructureData_util/test_break_symmetry_bulk.yml b/tests/tools/test_StructureData_util/test_break_symmetry_bulk.yml
new file mode 100644
index 000000000..345341d53
--- /dev/null
+++ b/tests/tools/test_StructureData_util/test_break_symmetry_bulk.yml
@@ -0,0 +1,33 @@
+parameters1:
+ atom:
+ element: Si
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.1
+ comp:
+ kmax: 5.0
+parameters2:
+ atom:
+ element: Si
+ jri: 981
+ lmax: 10
+ lnonsph: 6
+ rmt: 2.0
+ atom1:
+ element: Si
+ id: 16.1
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.2
+ atom2:
+ element: Si
+ id: 16.2
+ jri: 981
+ lmax: 11
+ lnonsph: 6
+ rmt: 2.1
+ z: 16
+ comp:
+ kmax: 5.0
diff --git a/tests/tools/test_common_aiida.py b/tests/tools/test_common_aiida.py
index b23fa745f..12cf29423 100644
--- a/tests/tools/test_common_aiida.py
+++ b/tests/tools/test_common_aiida.py
@@ -8,8 +8,8 @@
import pytest
-def test_create_group(capsys):
- 'Test group creation'
+def test_create_group(capsys, clear_database):
+ """Test group creation"""
from aiida_fleur.tools.common_aiida import create_group
from aiida.orm import Group, Dict
@@ -18,26 +18,29 @@ def test_create_group(capsys):
group = create_group(name='test_group', nodes=[para.pk, 'not-existent-uuid'], description='test_description')
captured = capsys.readouterr()
+ if '=4' in captured.out:
+ pk = 4 # when running all tests the import group counter is not reset...
+ else:
+ pk = 1
- assert captured.out == ('Group created with PK=1 and name test_group\n'
+ assert captured.out == (f'Group created with PK={pk} and name test_group\n'
'Skipping not-existent-uuid, it does not exist in the DB\n'
- 'added nodes: [{}] to group test_group 1\n'.format(para.pk))
-
+ f'added nodes: [{para.pk}] to group test_group {pk}\n')
para2 = para.clone()
para2.store()
group = create_group(name='test_group', nodes=[para2], add_if_exist=False)
captured = capsys.readouterr()
- assert captured.out == ('Group with name test_group and pk 1 already exists.\n'
- 'Nodes were not added to the existing group test_group\n')
+ assert captured.out == ('Group with name test_group and pk {} already exists.\n'
+ 'Nodes were not added to the existing group test_group\n'.format(pk))
group = create_group(name='test_group', nodes=[para2], add_if_exist=True)
captured = capsys.readouterr()
- assert captured.out == ('Group with name test_group and pk 1 already exists.\n'
+ assert captured.out == (f'Group with name test_group and pk {pk} already exists.\n'
'Adding nodes to the existing group test_group\n'
- 'added nodes: [{}] to group test_group 1\n'.format(para2.pk))
+ f'added nodes: [{para2.pk}] to group test_group {pk}\n')
assert isinstance(group, Group)
diff --git a/tests/tools/test_common_fleur_wf.py b/tests/tools/test_common_fleur_wf.py
index c8ca0e499..92646476a 100644
--- a/tests/tools/test_common_fleur_wf.py
+++ b/tests/tools/test_common_fleur_wf.py
@@ -17,6 +17,7 @@
# is_code
def test_is_code_interface(fixture_code):
+ """Test if is_code interface can take all inputs types without failure"""
from aiida_fleur.tools.common_fleur_wf import is_code
assert is_code('random_string') is None
@@ -160,15 +161,15 @@ def test_get_inputs_inpgen(fixture_code, generate_structure):
assert get_inputs_inpgen(**inputs) == returns
-@pytest.mark.skip(reason='Test is not implemented')
-def test_get_scheduler_extras():
- from aiida_fleur.tools.common_fleur_wf import get_scheduler_extras
-
-
# test_and_get_codenode
-
-
def test_test_and_get_codenode_inpgen(fixture_code):
+ """Tests for test_and_get_code_node function
+
+ test interface for cases:
+ if code exists and is right,
+ if code is wrong,
+ if code does not exists
+ """
from aiida_fleur.tools.common_fleur_wf import test_and_get_codenode
from aiida.orm import Code
from aiida.common.exceptions import NotExistent
@@ -198,6 +199,7 @@ def test_test_and_get_codenode_inpgen(fixture_code):
def test_get_kpoints_mesh_from_kdensity(generate_structure):
+ """Test genration of a kpoints mesh node from a given density"""
from aiida_fleur.tools.common_fleur_wf import get_kpoints_mesh_from_kdensity
from aiida.orm import KpointsData
@@ -206,10 +208,36 @@ def test_get_kpoints_mesh_from_kdensity(generate_structure):
assert isinstance(b, KpointsData)
-@pytest.mark.skip(reason='Test is not implemented')
def test_determine_favorable_reaction():
+ """Test favorable reaction function
+
+ which returns a list which ranks which reaction is energetically the most favorable.
+ We only test the way if the formation energies are provided
+ not when they have to be taken from the node
+ """
from aiida_fleur.tools.common_fleur_wf import determine_favorable_reaction
+ reaction_list = [
+ '1*Be12W->1*Be12W', '2*Be12W->1*Be2W+1*Be22W', '11*Be12W->5*W+6*Be22W', '1*Be12W->12*Be+1*W',
+ '1*Be12W->1*Be2W+10*Be'
+ ]
+ workchain_dict = {
+ 'Be12W': -0.21, #'4f685bc5-b5fb-46d3-aad6-e0f512c3313d',
+ 'Be2W': -0.3, #'045d3071-f442-46b4-8d6b-3c85d72b24d4',
+ 'Be22W': -0.1, #'1e32880a-bdc9-4081-a5da-be04860aa1bc',
+ 'W': 0.0, #'f8b12b23-0b71-45a1-9040-b51ccf379439',
+ 'Be': 0.0
+ }
+ best_order = [['11*Be12W->5*W+6*Be22W', -1.71], ['1*Be12W->12*Be+1*W', -0.21],
+ ['2*Be12W->1*Be2W+1*Be22W', -0.019999999999999962], ['1*Be12W->1*Be12W', 0.0],
+ ['1*Be12W->1*Be2W+10*Be', 0.09]]
+
+ reac_list = determine_favorable_reaction(reaction_list, workchain_dict)
+
+ assert len(reac_list) == len(reaction_list)
+ for i, reaction in enumerate(reac_list):
+ assert reaction == best_order[i]
+
# @pytest.mark.skip(reason="There seems to be now way to add outputs to CalcJobNode")
diff --git a/tests/tools/test_common_fleur_wf_util.py b/tests/tools/test_common_fleur_wf_util.py
index 797f9630a..e375dff32 100644
--- a/tests/tools/test_common_fleur_wf_util.py
+++ b/tests/tools/test_common_fleur_wf_util.py
@@ -27,6 +27,12 @@ def test_get_natoms_element_Be2W():
assert get_natoms_element('Be2W') == {'Be': 2, 'W': 1}
+def test_convert_frac_formula_BeW():
+ from aiida_fleur.tools.common_fleur_wf_util import convert_frac_formula
+
+ assert convert_frac_formula('Be0.5W0.5') == 'BeW'
+
+
def test_ucell_to_atompr():
from aiida_fleur.tools.common_fleur_wf_util import ucell_to_atompr
@@ -60,12 +66,6 @@ def test_get_atomprocent_Be24W2():
assert get_atomprocent('Be24W2') == {'Be': 24. / 26., 'W': 2. / 26.}
-#@pytest.mark.skip(reason='The function is not implemented')
-#def test_get_weight_procent():
-# from aiida_fleur.tools.common_fleur_wf_util import get_weight_procent
-# pass
-
-
def test_determine_formation_energy():
from aiida_fleur.tools.common_fleur_wf_util import determine_formation_energy
@@ -77,9 +77,15 @@ def test_determine_formation_energy():
assert form_en_dict == form_en_dict_exp
-@pytest.mark.skip(reason='Test is not implemented')
def test_determine_convex_hull():
from aiida_fleur.tools.common_fleur_wf_util import determine_convex_hull
+ from pyhull.convex_hull import ConvexHull
+
+ formation_en_grid = [[0.5, -1.0], [0.5, -0.5]]
+
+ hull = determine_convex_hull(formation_en_grid)
+
+ assert isinstance(hull, ConvexHull)
def test_inpgen_dict_set_mesh(generate_kpoints_mesh):
@@ -125,10 +131,20 @@ def test_convert_eq_to_dict():
assert convert_eq_to_dict('1*Be12Ti->10*Be+1*Be2Ti+5*Be') == res_dict
-@pytest.mark.skip(reason='Test is not implemented')
def test_get_enhalpy_of_equation():
from aiida_fleur.tools.common_fleur_wf_util import get_enhalpy_of_equation
+ reaction_list = [
+ '1*Be12W->1*Be12W', '2*Be12W->1*Be2W+1*Be22W', '11*Be12W->5*W+6*Be22W', '1*Be12W->12*Be+1*W',
+ '1*Be12W->1*Be2W+10*Be'
+ ]
+ formenergydict = {'Be12W': -0.21, 'Be2W': -0.3, 'Be22W': -0.1, 'W': 0.0, 'Be': 0.0}
+ results = [0.0, -0.019999999999999962, -1.71, -0.21, 0.09]
+
+ for i, reaction in enumerate(reaction_list):
+ result = get_enhalpy_of_equation(reaction, formenergydict)
+ assert result == results[i]
+
@pytest.mark.parametrize('test_input,expected', [('C7H16+O2 -> CO2+H2O', '1*C7H16+11*O2 ->7* CO2+8*H2O'),
('Be12W->Be2W+W+Be', None), ('Be12WO->Be2WO+W+Be+O2', None),
@@ -138,6 +154,20 @@ def test_balance_equation(test_input, expected):
assert balance_equation(test_input) == expected
-@pytest.mark.skip(reason='Test is not implemented')
def test_check_eos_energies():
from aiida_fleur.tools.common_fleur_wf_util import check_eos_energies
+
+ energylist = [-1, -2, -3, -2, -4, -3, -2, -1]
+ abnormality, abnormalityindexlist = check_eos_energies(energylist)
+ assert abnormality
+ assert abnormalityindexlist == [3]
+
+ energylist = [-1, -2, -3, -2, -2, -3, -2, -1]
+ abnormality, abnormalityindexlist = check_eos_energies(energylist)
+ assert not abnormality
+ assert abnormalityindexlist == []
+
+ energylist = [-1, -2, -3, -4, -5, -3, -2, -1]
+ abnormality, abnormalityindexlist = check_eos_energies(energylist)
+ assert not abnormality
+ assert abnormalityindexlist == []
diff --git a/tests/tools/test_create_corehole.py b/tests/tools/test_create_corehole.py
index f33128211..d1f27c04c 100644
--- a/tests/tools/test_create_corehole.py
+++ b/tests/tools/test_create_corehole.py
@@ -1,3 +1,134 @@
# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''Contains tests for create_corehole functions.'''
+import pytest
+from aiida import orm
+
# create_corehole_para
# test interface of corehole para, that the parameter dict that comes out is right
+PARAMETERS2 = {
+ 'atom1': {
+ 'element': 'Si',
+ 'id': 14.1,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ }, #'econfig': '[He] 2s2 2p6 | 3s2 3p2', 'lo': ''},
+ 'atom2': {
+ 'element': 'Si',
+ 'z': 14,
+ 'id': 14.2,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+}
+
+
+def test_create_corehole_para(generate_structure, data_regression):
+ """Test if the create corehole para function has thr right interface and returns
+ the correct things
+ """
+ from aiida_fleur.tools.create_corehole import create_corehole_para
+ from aiida_fleur.tools.StructureData_util import break_symmetry
+
+ dict2 = orm.Dict(dict=PARAMETERS2)
+ struc = generate_structure() #Si
+ struc2, para_new = break_symmetry(struc, parameterdata=dict2)
+ parameters1 = create_corehole_para(struc2, kind='Si1', econfig='[He] 2s1 2p6 | 3s2 3p3', parameterdata=para_new)
+ assert isinstance(parameters1, orm.Dict)
+
+ # with no parameterdata to modify
+ parameters2 = create_corehole_para(struc2, kind='Si1', econfig='[He] 2s1 2p6 | 3s2 3p3')
+ assert isinstance(parameters2, orm.Dict)
+
+ data_regression.check({
+ 'parameters1': parameters1.get_dict(),
+ 'parameters2': parameters2.get_dict(),
+ })
+
+
+'''
+# from old, test idea for create_corehole_fleurinp
+ids = [] #13924]#, 13925]#, 13926, 13927, 13928, 13929, 13930, 13931, 13932, 13933, 13934, 13935]
+#ids = [479, 480, 481, 482, 537]# O12W4, O12W4, O6W2, O6W2, O36W3Y18
+
+kind = 'W1'
+econfig = '[Kr] 5s2 4d10 4f13 | 5p6 5d5 6s2'
+para1 = Dict(
+ dict={
+ 'title': 'A test calculation of Tungsten',
+ 'input': {
+ 'film': False,
+ 'cartesian': True,
+ },
+ 'atom': {
+ 'element': 'W',
+ 'jri': 833,
+ 'rmt': 2.3,
+ 'dx': 0.015,
+ 'lmax': 8,
+ 'lo': '5p',
+ 'econfig': '[Kr] 5s2 4d10 4f14| 5p6 5d4 6s2',
+ },
+ 'soc': {
+ 'theta': 0.0,
+ 'phi': 0.0
+ },
+ 'comp': {
+ 'kmax': 3.5,
+ 'gmax': 2.9,
+ },
+ 'kpt': {
+ 'nkpt': 200,
+ }
+ })
+#para1.store()
+#pprint(para1.get_dict())
+
+for id in ids:
+ s = load_node(id)
+ new_s, para = bs(s, atoms=[], site=[0, 1], pos=[(0.0, 0.0, 0, 0)], parameterData=para1)
+ #print new_s.sites
+ #pprint(para.get_dict())
+ res = create_corehole(new_s, kind, econfig, para)
+ #print res
+ #pprint(para.get_dict())
+ #pprint(res.get_dict())
+
+# test create_corehole_fleurinp
+#fleurinp = load_node(14039) # W film
+
+inpxmlfile1 = '../inp_xml_files/W/inp.xml'
+inpxmlfile = os.path.abspath(inpxmlfile1)
+fleurinp = FleurinpData(files=[inpxmlfile])
+species = 'W-1'
+stateocc = {'(5d3/2)': (2.5, 0.0), '(4f7/2)': (3.5, 4.0)}
+pos = []
+coreconfig = 'same'
+valenceconfig = 'same'
+#pprint(fleurinp.inp_dict)
+
+new_inp = create_corehole_fleurinp(fleurinp, species, stateocc)
+print(new_inp)
+
+etree = ''
+change = [(1, 2)]
+res = write_change(etree, change)
+#res.write('.outtree')
+print(res)
+'''
diff --git a/tests/tools/test_create_corehole/test_create_corehole_para.yml b/tests/tools/test_create_corehole/test_create_corehole_para.yml
new file mode 100644
index 000000000..44a4aa10a
--- /dev/null
+++ b/tests/tools/test_create_corehole/test_create_corehole_para.yml
@@ -0,0 +1,40 @@
+parameters1:
+ atom1:
+ econfig: '[He] 2s1 2p6 | 3s2 3p3'
+ element: Si
+ id: '14.1'
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.1
+ atom2:
+ element: Si
+ id: '14.1'
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.1
+ z: 14
+ atom3:
+ element: Si
+ id: '14.2'
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.1
+ atom4:
+ element: Si
+ id: '14.2'
+ jri: 981
+ lmax: 12
+ lnonsph: 6
+ rmt: 2.1
+ z: 14
+ comp:
+ kmax: 5.0
+parameters2:
+ atom:
+ econfig: '[He] 2s1 2p6 | 3s2 3p3'
+ element: Si
+ id: 14.1
+ name: corehole
diff --git a/tests/tools/test_dict_util.py b/tests/tools/test_dict_util.py
index ceebbb6e1..d848a6fd2 100644
--- a/tests/tools/test_dict_util.py
+++ b/tests/tools/test_dict_util.py
@@ -88,3 +88,13 @@ def test_extract_elementpara_interface_W():
para_dict = {'a': 1, 'atom': {'element': 'H', 'rmt': 1}, 'atom1': {'element': 'W', 'rmt': 4}}
assert extract_elementpara(para_dict, 'W') == {'a': 1, 'atom1': {'element': 'W', 'rmt': 4}}
+
+
+def test_clean_nones():
+ from aiida_fleur.tools.dict_util import clean_nones
+
+ test_dict = {1: None, 2: 3, 4: {1: None}}
+ expected = {2: 3, 4: {}}
+ out_dict = clean_nones(test_dict)
+
+ assert out_dict == expected
diff --git a/tests/tools/test_graph_fleur.py b/tests/tools/test_graph_fleur.py
deleted file mode 100644
index fc202c169..000000000
--- a/tests/tools/test_graph_fleur.py
+++ /dev/null
@@ -1,31 +0,0 @@
-#!/usr/bin/env python
-# -*- coding: utf-8 -*-
-''' Contains test the fleur specific graph gernation routine. '''
-from __future__ import absolute_import
-import pytest
-
-# These tests need dot/graphviz... which is not autoinstalled in the python env... so far
-# Therefore I uncomment these tests for know, because they will fail on travis.
-# TODO find a way (aiidas problem) to set up a clean environment
-'''
-# test draw_graph
-@pytest.mark.usefixtures("aiida_env")
-def test_draw_graph_if_produces_file():
- """
- does the individual fleur_draw_graph routine produce a file?
- """
- import os
- from aiida_fleur.tools.graph_fleur import draw_graph
- from aiida.orm import Node
-
- # TODO store a real graph and test if it is represented right...
- node = Node()
- outfile_expected = 'None.dot'
- exit_expected = 0
- exit_status, output_file_name = draw_graph(node)
- os.remove(output_file_name)
-
- assert exit_status == exit_expected
- assert output_file_name == outfile_expected
-
-'''
diff --git a/tests/tools/test_io_routines.py b/tests/tools/test_io_routines.py
index a32527cd8..2cc7cef7c 100644
--- a/tests/tools/test_io_routines.py
+++ b/tests/tools/test_io_routines.py
@@ -60,6 +60,8 @@ def test_compress_fleuroutxml():
testfilepath = abspath('./files/outxml/BeTi_out.xml')
dest_path = testfilepath.replace('.xml', '_test.xml')
+ testfilepath_broken = abspath('./files/outxml/special/broken_first_BeTi_out.xml')
+ dest_path2 = testfilepath_broken.replace('.xml', '_test.xml')
niter_file = 19
xpath_iter = '/fleurOutput/scfLoop/iteration'
xpath_eig = '/fleurOutput/scfLoop/iteration/eigenvalues'
@@ -94,5 +96,9 @@ def get_npath(filepath, xpath):
assert niter3 == niter_file # check if no iteration deleted
+ # test if broken file will not generate an error
+ compress_fleuroutxml(testfilepath_broken, dest_file_path=dest_path2, iterations_to_keep=25)
+
# cleanup
remove(dest_path)
+ remove(dest_path2)
diff --git a/tests/tools/test_merge_parameter.py b/tests/tools/test_merge_parameter.py
new file mode 100644
index 000000000..9fb0e5c7f
--- /dev/null
+++ b/tests/tools/test_merge_parameter.py
@@ -0,0 +1,257 @@
+# -*- coding: utf-8 -*-
+###############################################################################
+# Copyright (c), Forschungszentrum Jülich GmbH, IAS-1/PGI-1, Germany. #
+# All rights reserved. #
+# This file is part of the AiiDA-FLEUR package. #
+# #
+# The code is hosted on GitHub at https://github.com/JuDFTteam/aiida-fleur #
+# For further information on the license, see the LICENSE.txt file #
+# For further information please visit http://www.flapw.de or #
+# http://aiida-fleur.readthedocs.io/en/develop/ #
+###############################################################################
+'''Contains tests merge_parameters.'''
+import pytest
+from aiida import orm
+
+PARAMETERS1 = {
+ 'atom': {
+ 'element': 'Si',
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ }, #'econfig': '[He] 2s2 2p6 | 3s2 3p2', 'lo': ''},
+ 'comp': {
+ 'kmax': 5.0,
+ },
+ 'kpt': {
+ 'div1': 17,
+ 'tkb': 0.0005
+ }
+}
+PARAMETERS2 = {
+ 'atom1': {
+ 'element': 'Si',
+ 'id': 16.1,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ }, #'econfig': '[He] 2s2 2p6 | 3s2 3p2', 'lo': ''},
+ 'atom2': {
+ 'element': 'Si',
+ 'z': 16,
+ 'id': 16.4,
+ 'rmt': 2.1,
+ 'jri': 981,
+ 'lmax': 12,
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0,
+ }
+}
+PARAMETERS3 = PARAMETERS1.copy()
+PARAMETERS3['atom']['element'] = 'Fe'
+
+
+def test_merge_parameter():
+ """Test if merge_parameter merges atom keys in dicts right
+ """
+ from aiida_fleur.tools.merge_parameter import merge_parameter
+ from aiida.common.exceptions import InputValidationError
+
+ dict1 = orm.Dict(dict=PARAMETERS1).store()
+ dict2 = orm.Dict(dict=PARAMETERS2).store()
+ dict3 = orm.Dict(dict=PARAMETERS3).store()
+ # otherwise we we can still change the dicts and therefore the PARAMETERS
+
+ result = merge_parameter(dict2, dict2)
+ assert isinstance(result, orm.Dict)
+ assert result.get_dict() == PARAMETERS2
+
+ res_exp = {
+ 'kpt': {
+ 'tkb': 0.0005,
+ 'div1': 17
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom0': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ },
+ 'atom1': {
+ 'id': 16.1,
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Si',
+ 'lnonsph': 6
+ },
+ 'atom2': {
+ 'z': 16,
+ 'id': 16.4,
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Si',
+ 'lnonsph': 6
+ }
+ }
+
+ result1 = merge_parameter(dict1, dict2)
+ assert isinstance(result1, orm.Dict)
+ assert result1.get_dict() == res_exp
+
+ res_exp = {
+ 'kpt': {
+ 'tkb': 0.0005,
+ 'div1': 17
+ },
+ 'atom': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ },
+ 'comp': {
+ 'kmax': 5.0
+ }
+ }
+ result2 = merge_parameter(dict1, dict3)
+ assert isinstance(result2, orm.Dict)
+ assert result2.get_dict() == res_exp
+
+ # wrong input
+ with pytest.raises(InputValidationError):
+ merge_parameter(dict2, 'string')
+ with pytest.raises(InputValidationError):
+ merge_parameter(123123, dict2)
+
+
+def test_merge_parameters():
+ """Test if merge_parameters works for a given set
+ """
+ from aiida_fleur.tools.merge_parameter import merge_parameters
+
+ dict1 = orm.Dict(dict=PARAMETERS1).store()
+ dict2 = orm.Dict(dict=PARAMETERS2).store()
+ dict3 = orm.Dict(dict=PARAMETERS3).store()
+
+ # overwrite seems broken...
+ res_exp = {
+ 'kpt': {
+ 'tkb': 0.0005,
+ 'div1': 17
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom0': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ },
+ 'atom1': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ }
+ }
+ result1 = merge_parameters([dict1, dict1], overwrite=False)
+ assert isinstance(result1, orm.Dict)
+ assert result1.get_dict() == res_exp
+
+ res_exp = {
+ 'kpt': {
+ 'tkb': 0.0005,
+ 'div1': 17
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom0': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ },
+ 'atom1': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ }
+ }
+ result2 = merge_parameters([dict1, dict1], overwrite=True)
+ assert isinstance(result2, orm.Dict)
+ assert result2.get_dict() == res_exp
+
+ res_exp = {
+ 'kpt': {
+ 'tkb': 0.0005,
+ 'div1': 17
+ },
+ 'comp': {
+ 'kmax': 5.0
+ },
+ 'atom0': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ },
+ 'atom1': {
+ 'id': 16.1,
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Si',
+ 'lnonsph': 6
+ },
+ 'atom2': {
+ 'z': 16,
+ 'id': 16.4,
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Si',
+ 'lnonsph': 6
+ },
+ 'atom3': {
+ 'jri': 981,
+ 'rmt': 2.1,
+ 'lmax': 12,
+ 'element': 'Fe',
+ 'lnonsph': 6
+ }
+ }
+ result3 = merge_parameters([dict1, dict2, dict3])
+ assert isinstance(result3, orm.Dict)
+ assert result3.get_dict() == res_exp
+
+
+def test_merge_parameter_cf():
+ """Test calcfunction of merge_parameter
+ """
+ from aiida_fleur.tools.merge_parameter import merge_parameter_cf
+
+ dict1 = orm.Dict(dict=PARAMETERS1)
+
+ result = merge_parameter_cf(dict1, dict1)
+ assert isinstance(result, orm.Dict)
+ assert result.get_dict() == PARAMETERS1
+ assert result.is_stored
diff --git a/tests/tools/test_read_cif_folder.py b/tests/tools/test_read_cif_folder.py
index 2c06b2bf2..d1143851f 100644
--- a/tests/tools/test_read_cif_folder.py
+++ b/tests/tools/test_read_cif_folder.py
@@ -1,13 +1,11 @@
# -*- coding: utf-8 -*-
'''Contains tests for read and with work cif file routines.'''
-from __future__ import absolute_import
-from __future__ import print_function
import pytest
# read-cif_folder
-@pytest.mark.skip(reason='Test not implemented')
+#@pytest.mark.skip(reason='Test not implemented')
def test_read_cif_folder_interface(temp_dir):
"""
this test set reads in the cif files in the ../files/cif/ directory and subdirs
@@ -17,32 +15,46 @@ def test_read_cif_folder_interface(temp_dir):
import os
from aiida_fleur.tools.read_cif_folder import read_cif_folder
import aiida_fleur
+ from aiida import orm
path = os.path.dirname(aiida_fleur.__file__)
- cif_folderpath = os.path.join(path, 'tests/files/cif/')
+ cif_folderpath = os.path.join(path, '../tests/files/cif/')
out_filename = os.path.join(temp_dir, 'out.txt')
-
+ add_extra = {'test': 1}
#read_in
- structure_data, filenames = read_cif_folder(path=os.getcwd(),
+ structure_data, filenames = read_cif_folder(path=cif_folderpath,
recursive=True,
store=True,
log=True,
comments='Test_comment',
- extras={'test': 1},
+ extras=add_extra,
logfile_name=out_filename)
- structure_data, filenames = read_cif_folder(path=cif_folderpath,
- recursive=False,
- store=False,
- log=False,
- comments='',
- extras='')
#test number of structurs written
#test number of cif files written
#test if extras are set right
#test prov
#test
+ for structure in structure_data:
+ assert isinstance(structure, orm.StructureData)
+ assert structure.is_stored
+ assert structure.extras['test'] == 1
+
+ assert len(structure_data) == len(filenames)
#read_in again
- # test if cif files are not rewritten.
- assert False
+ structure_data, filenames = read_cif_folder(path=cif_folderpath,
+ recursive=False,
+ store=False,
+ log=True,
+ comments='',
+ extras='myproject',
+ logfile_name=out_filename)
+ for structure in structure_data:
+ assert isinstance(structure, orm.StructureData)
+ assert not structure.is_stored
+ assert 'test' not in structure.extras
+ #assert structure.extras['specification'] == 'myproject'
+ assert 'specification' not in structure.extras
+ # extras get only written if structures are stored
+ assert len(structure_data) == len(filenames)
diff --git a/tests/workflows_regression_manually.py b/tests/workflows_regression_manually.py
new file mode 100644
index 000000000..b8b73cc3c
--- /dev/null
+++ b/tests/workflows_regression_manually.py
@@ -0,0 +1,14 @@
+# -*- coding: utf-8 -*-
+
+# this should be executed at least once before a release
+# It runs all launch commands form the aiida-fleur cmdline once
+# with defaults for a given inpgen or fleur code or it use
+
+#aiida-fleur launch inpgen
+#aiida-fleur launch fleur
+#aiida-fleur launch scf
+#aiida-fleur launch eos
+#aiida-fleur launch banddos
+#aiida-fleur launch relax
+#aiida-fleur launch corehole
+#aiida-fleur launch init_cls
diff --git a/tests/workflows_regression_manually.sh b/tests/workflows_regression_manually.sh
new file mode 100644
index 000000000..2e010b3d3
--- /dev/null
+++ b/tests/workflows_regression_manually.sh
@@ -0,0 +1,29 @@
+#!/bin/bash
+# Todo: parse as argument the fleur and inpgen code you want to use, optional options, if non default for the used machine,
+#
+# This test set should be executed at least once before a release
+# It runs all launch commands form the aiida-fleur cmdline once
+# with defaults for a given inpgen or fleur code or it use
+# the materials and all other parameter are definded in the submission tests...
+
+FLEUR=713 #iff pc
+INPGEN='497d15d9-9e53-434a-9b32-b85256fe3a69' #712 # iff pc
+STRUCTURE=1604
+SUBMIT=true
+FLEURINP=1916 # Tungesten
+OPTIONS=49361 # claix
+REMOTE=1921 # W on claix
+
+# import a some nodes needed for the regression tests
+verdi import ./files/exports/base_export_regression_tests.tar.gz
+
+# Run or submit all workflows via CLI
+
+aiida-fleur launch inpgen --inpgen $INPGEN
+aiida-fleur launch fleur --fleur $FLEUR -P $REMOTE
+aiida-fleur launch scf --inpgen $INPGEN --fleur $FLEUR
+aiida-fleur launch eos --inpgen $INPGEN --fleur $FLEUR
+#aiida-fleur launch banddos
+aiida-fleur launch relax --inpgen $INPGEN --fleur $FLEUR
+#aiida-fleur launch corehole
+#aiida-fleur launch init_cls
|