Skip to content

Commit

Permalink
Adjustments to the protocols/generator for Fleur code (#265)
Browse files Browse the repository at this point in the history
* Delete 'serial' key from default SCF wf parameters

The interface has changed, the default is False, so it is not needed.
In general for flexibility we might have to change some of the other
queue parameters through, since over the common workflow the default scf
cannot be changed.

* Ignore `kpoints_distance` input if a `kpt` specification comes from the parameters of the reference workchain

* Turn off writing of atom ids in get_parameters

* Adjust protocols, parse the protocol to inpgen, use fleur protocols

* Fix that protocol name was not given to inpgen

* Decouple protocol name in common workflows with profile/protocol used in
the inpgen of fleur

* Add oxides_validation protocol

* Add oxides_validation protocol also to the FleurCommonRelaxInputGenerator

* Fix wrong name of gamma option in fleur protocol

* Make sure that the gamma option is set for all relax workchains not just for the reference workchain

* Fix for last commit

* Add oxides_validation to valid type for the protocol input

* Incorporate Gregor's changes

* Add remote_folder output to FleurCommonRelaxWorkChain

* Move valid protocols to fleur workchain

* Add `verification-pbe-v1` protocol

* Add missing description

* Update aiida-fleur dependency to make sure the common workflows have everything they need

* Add extractor for TS contribution for FleurCommonRelaxWorkChain

* Add fallback solution for extracting the TS contribution directly from the out.xml

For calculations that do not already extract this information in the main fleur parser

Co-authored-by: Jens Bröder <j.broeder@fz-juelich.de>
Co-authored-by: Jens Broeder <broeder-j@users.noreply.github.com>
  • Loading branch information
3 people authored Apr 6, 2022
1 parent 2fd47d0 commit ac214b1
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 19 deletions.
51 changes: 51 additions & 0 deletions aiida_common_workflows/workflows/relax/fleur/extractors.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# -*- coding: utf-8 -*-
"""
Collects some functions to postprocess a `FleurCommonRelaxWorkChain`.
"""


def get_ts_energy(common_relax_workchain):
"""
Return the TS value of a concluded FleurCommonRelaxWorkChain.
T the fictitious temperature due to the presence of a smearing and S is
the entropy. The units must be eV.
In Fleur this contribution is directly available in the output parameters
of the Fleur calculation
"""
from aiida.common import LinkType
from aiida.orm import WorkChainNode
from aiida.plugins import WorkflowFactory
from masci_tools.io.io_fleurxml import load_outxml
from masci_tools.util.constants import HTR_TO_EV
from masci_tools.util.schema_dict_util import evaluate_attribute

if not isinstance(common_relax_workchain, WorkChainNode):
return ValueError('The input is not a workchain (instance of `WorkChainNode`)')
if common_relax_workchain.process_class != WorkflowFactory('common_workflows.relax.fleur'):
return ValueError('The input workchain is not a `FleurCommonRelaxWorkChain`')

fleur_relax_wc = common_relax_workchain.get_outgoing(link_type=LinkType.CALL_WORK).one().node
fleur_calc_out = fleur_relax_wc.outputs.last_scf.last_calc

output_parameters = fleur_calc_out.output_parameters
ts = None #pylint: disable=invalid-name
if 'ts_energy' in output_parameters.keys():
ts = output_parameters['ts_energy'] #pylint: disable=invalid-name
elif fleur_relax_wc.is_finished_ok:
#This check makes sure that the parsing worked before so we don't get
#nasty surprises in load_outxml

with fleur_calc_out.retrieved.open('out.xml', 'rb') as file:
xmltree, schema_dict = load_outxml(file)
try:
ts_all = evaluate_attribute(
xmltree, schema_dict, 'value', tag_name='tkbtimesentropy', iteration_path=True, list_return=True
)
except ValueError:
pass
else:
if ts_all:
ts = ts_all[-1] * HTR_TO_EV #pylint: disable=invalid-name

return ts
36 changes: 29 additions & 7 deletions aiida_common_workflows/workflows/relax/fleur/generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,12 @@ class FleurCommonRelaxInputGenerator(CommonRelaxInputGenerator):
},
'precise': {
'description': 'high level of accuracy'
},
'oxides_validation': {
'description': 'high level of accuracy. Used for validating oxide results for common-workflows'
},
'verification-pbe-v1': {
'description': 'high level of accuracy. Used for validating oxide results for common-workflows'
}
}

Expand All @@ -54,6 +60,9 @@ def define(cls, spec):
spec.inputs['spin_type'].valid_type = ChoiceType((SpinType.NONE, SpinType.COLLINEAR))
spec.inputs['relax_type'].valid_type = ChoiceType((RelaxType.NONE, RelaxType.POSITIONS))
spec.inputs['electronic_type'].valid_type = ChoiceType((ElectronicType.METAL, ElectronicType.INSULATOR))
spec.inputs['protocol'].valid_type = ChoiceType(
('fast', 'moderate', 'precise', 'oxides_validation', 'verification-pbe-v1')
)
spec.input('engines.inpgen.code', valid_type=orm.Code, serializer=orm.load_code)
spec.input('engines.inpgen.options', valid_type=dict, required=False)
spec.inputs['engines']['relax']['code'].valid_type = CodeType('fleur.fleur')
Expand Down Expand Up @@ -138,8 +147,15 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder:
raise ValueError(f'relaxation type `{relax_type.value}` is not supported')

# We reduce the number of sigfigs for the cell and atom positions accounts for less
# numerical inpgen errors during relaxation and accuracy is still enough for this purpose
settings = orm.Dict(dict={'significant_figures_cell': 9, 'significant_figures_position': 9})
# numerical inpgen errors during relaxation and accuracy is still enough for this purpose
# We also currently assume that all common-workflow protocols exist in fleur
settings = orm.Dict(
dict={
'significant_figures_cell': 9,
'significant_figures_position': 9,
'profile': protocol['inpgen-protocol']
}
)

wf_para = orm.Dict(dict=wf_para_dict)

Expand All @@ -153,24 +169,30 @@ def _construct_builder(self, **kwargs) -> engine.ProcessBuilder:
'forcemix': 'straight'
},
'use_relax_xml': True,
'serial': False,
'mode': relaxation_mode,
}
protocol_scf_para = protocol.get('scf', {})
kmax = protocol_scf_para.pop('k_max_cutoff', None)
kmax = protocol_scf_para.pop('k_max_cutoff', None) # for now always None, later consider clean up

if molecule: # We want to use only one kpoint, can be overwritten by user input
protocol_scf_para['kpoints_distance'] = 100000000
# In addition we might want to use a different basis APW+LO?

wf_para_scf_dict = recursive_merge(default_scf, protocol_scf_para)
wf_para_scf = orm.Dict(dict=wf_para_scf_dict)

if reference_workchain is not None:
parameters = get_parameters(reference_workchain)
if 'kpt' in parameters.get_dict():
wf_para_scf_dict.pop('kpoints_distance', None)
if protocol_scf_para.get('kpoints_force_gamma', False):
parameters = parameters.get_dict()
parameters['kpt']['gamma'] = True
parameters = orm.Dict(dict=parameters)

wf_para_scf = orm.Dict(dict=wf_para_scf_dict)

# User specification overrides previous workchain!
if 'calc_parameters' in kwargs.keys():
if 'calc_parameters' in kwargs:
parameters = kwargs.pop('calc_parameters')

parameters, structure = prepare_calc_parameters(parameters, spin_type, magnetization_per_site, structure, kmax)
Expand Down Expand Up @@ -298,7 +320,7 @@ def get_parameters(reference_workchain):
# Be aware that this parameter node is incomplete. LOs and econfig is
# currently missing for example, also we do not reuse the same kpoints.
# the density is likely the same, but the set may vary.
parameters = fleurinp.get_parameterdata_ncf() # This is not a calcfunction!
parameters = fleurinp.get_parameterdata_ncf(write_ids=False) # This is not a calcfunction!

return parameters

Expand Down
52 changes: 42 additions & 10 deletions aiida_common_workflows/workflows/relax/fleur/protocol.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
moderate:
name: 'moderate'
description: 'Protocol to relax a structure with normal precision at moderate computational cost.'
inpgen-protocol: 'moderate'
description: 'Protocol to relax a structure with normal precision at moderate computational cost. This relies on the "moderate" protocol of the fleur code.'
relax:
relax_iter: 5
change_mixing_criterion: 0.025
run_final_scf: true
scf:
density_converged: 0.00002
kpoints_distance: 0.2
k_max_cutoff: 4.0
fleur_runmax: 2
itmax_per_run: 120
force_dict:
Expand All @@ -18,14 +17,13 @@ moderate:

precise:
name: 'precise'
description: 'Protocol to relax a structure with high precision at higher computational cost.'
inpgen-protocol: 'precise'
description: 'Protocol to relax a structure with high precision at higher computational cost. This relies on the "precise" protocol of the fleur code.'
relax:
relax_iter: 10
change_mixing_criterion: 0.025
run_final_scf: true
scf:
density_converged: 0.000002
k_max_cutoff: 5.0
kpoints_distance: 0.1
fleur_runmax: 3
itmax_per_run: 120
Expand All @@ -36,19 +34,53 @@ precise:

fast:
name: 'fast'
description: 'Protocol to relax a structure with low precision at minimal computational cost for testing purposes.'
inpgen-protocol: 'fast'
description: 'Protocol to relax a structure with low precision at minimal computational cost for testing purposes. This relies on the "fast" protocol of the fleur code.'
relax:
relax_iter: 3
change_mixing_criterion: 0.025
run_final_scf: true
scf:
fleur_runmax: 2
itmax_per_run: 120
force_converged: 0.001
density_converged: 0.0002
k_max_cutoff: 3.2
kpoints_distance: 0.4
force_dict:
qfix: 2
forcealpha: 1.0
forcemix: 'straight'

oxides_validation:
name: 'oxides_validation'
inpgen-protocol: 'oxides_validation'
description: 'Protocol to relax a structure with high precision at higher computational cost. This relies on the "precise" protocol of the fleur code.'
relax:
relax_iter: 10
change_mixing_criterion: 0.025
run_final_scf: true
scf:
kpoints_distance: 0.1
kpoints_force_gamma: true
fleur_runmax: 3
itmax_per_run: 120
force_dict:
qfix: 2
forcealpha: 0.50
forcemix: 'straight'

verification-pbe-v1:
name: 'verification-pbe-v1'
inpgen-protocol: 'oxides_validation'
description: 'Protocol to relax a structure with high precision at higher computational cost. This relies on the "oxides_validation" protocol of the fleur code.'
relax:
relax_iter: 10
change_mixing_criterion: 0.025
run_final_scf: true
scf:
kpoints_distance: 0.06
kpoints_force_gamma: true
fleur_runmax: 3
itmax_per_run: 120
force_dict:
qfix: 2
forcealpha: 0.50
forcemix: 'straight'
3 changes: 3 additions & 0 deletions aiida_common_workflows/workflows/relax/fleur/workchain.py
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ def convert_outputs(self):
if 'optimized_structure' in outputs:
self.out('relaxed_structure', outputs.optimized_structure)

if 'last_scf' in outputs:
self.out('remote_folder', outputs.last_scf.last_calc.remote_folder)

output_parameters = outputs.output_relax_wc_para
out_para_dict = output_parameters.get_dict()
if 'total_magnetic_moment_cell' in out_para_dict:
Expand Down
5 changes: 3 additions & 2 deletions setup.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"aiida-castep>=1.2.0a5",
"aiida-core[atomic_tools]~=1.6",
"aiida-cp2k~=1.3",
"aiida-fleur>=1.1.4",
"aiida-fleur>=1.3.0",
"aiida-gaussian",
"aiida-nwchem>=2.1.0",
"aiida-orca",
Expand All @@ -32,7 +32,8 @@
"pymatgen<=2021.3.3",
"sqlalchemy<1.4",
"ase!=3.20.*",
"pint~=0.16"
"pint~=0.16",
"masci-tools~=0.9"
],
"extras_require": {
"docs": [
Expand Down

0 comments on commit ac214b1

Please sign in to comment.