diff --git a/mpds_aiida/calc_templates/ext_metallic.yml b/mpds_aiida/calc_templates/ext_metallic.yml new file mode 100644 index 0000000..fc5d492 --- /dev/null +++ b/mpds_aiida/calc_templates/ext_metallic.yml @@ -0,0 +1,146 @@ +codes: + crystal: + Pcrystal@yascheduler + +options: + need_phonons: true + need_elastic_constants: true + need_properties: false + recursive_update: true + try_oxi_if_fails: true + is_magnetic: true + optimize_structure: optimise + +basis_family: MPDSBSL_NEUTRAL_24 + +default: + crystal: + scf: + k_points: [18, 54] + dft: + SPIN: True + xc: PBE0 + grid: XLGRID + numerical: + TOLLDENS: 8 + TOLLGRID: 16 + numerical: + TOLDEE: 9 + BIPOSIZE: 256000000 + EXCHSIZE: 256000000 + TOLINTEG: [20, 20, 20, 20, 40] + FMIXING: 80 + SMEAR: 0.001 + MAXCYCLE: 500 + fock_mixing: ANDERSON + post_scf: ['PPAN'] + +calculations: + optimise: + metadata: + label: 'Geometry optimization' + parameters: + crystal: + geometry: + optimise: + hessian: HESSIDEN + convergence: + TOLDEE: 9 + on_error: + 300: + crystal: + scf: + numerical: + MAXCYCLE: 1000 + 301: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + 303: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + 304: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + 305: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + 306: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + phonons: + metadata: + label: 'Phonon frequencies' + parameters: + crystal: + geometry: + phonons: + TEMPERAT: [35, 5.7125, 1000] + SCELPHONO: [[1, 1, 0], [-1, 1, 0], [0, 0, 2]] + on_error: + 300: + crystal: + scf: + numerical: + MAXCYCLE: 1000 + 303: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 + elastic_constants: + metadata: + label: 'Elastic constants' + parameters: + crystal: + geometry: + elastic_constants: + type: ELASTCON + on_error: + 300: + crystal: + scf: + numerical: + MAXCYCLE: 1000 + 303: + crystal: + scf: + k_points: [36, 72] + numerical: + TOLLDENS: 10 + TOLLGRID: 18 + numerical: + TOLPSEUD: 10 diff --git a/mpds_aiida/workflows/mpds.py b/mpds_aiida/workflows/mpds.py index 1b5b706..ace53c4 100644 --- a/mpds_aiida/workflows/mpds.py +++ b/mpds_aiida/workflows/mpds.py @@ -3,14 +3,15 @@ The MPDS workflow for AiiDA that gets structure with MPDS query """ import os -import time import random +import time import numpy as np +from aiida_crystal_dft.utils import get_data_class from httplib2 import ServerNotFoundError +from mpds_client import APIError, MPDSDataRetrieval -from aiida_crystal_dft.utils import get_data_class -from mpds_client import MPDSDataRetrieval, APIError +from ..chemical_formulae import parse_formula from .crystal import MPDSCrystalWorkChain @@ -29,7 +30,7 @@ def define(cls, spec): spec.exit_code(503, 'ERROR_NO_HITS', message='Request returned nothing') spec.exit_code(504, 'ERROR_SERVER_NOT_FOUND', message='MPDS server not found') - def get_geometry(self): + def get_geometry(self, elements_check=False): """ Getting geometry from MPDS database """ # check for API key @@ -50,6 +51,7 @@ def get_geometry(self): answer = client.get_data( query_dict, fields={'S': [ + 'chemical_formula', 'cell_abc', 'sg_n', 'basis_noneq', @@ -69,7 +71,18 @@ def get_geometry(self): self.report(f'MPDS API error: {str(ex)}') return self.exit_codes.ERROR_SERVER_NOT_FOUND - structs = [client.compile_crystal(line, flavor='ase') for line in answer] + structs = [] + for line in answer: + if line: + structs.append( + client.compile_crystal( + line, + flavor='ase', + elements_check=elements_check, + elements_counter=parse_formula(line[0]) + ) + ) + structs = list(filter(None, structs)) if not structs: return self.exit_codes.ERROR_NO_HITS diff --git a/scripts/aiida_submit_ext_scheme.py b/scripts/aiida_submit_ext_scheme.py new file mode 100644 index 0000000..6cd79f2 --- /dev/null +++ b/scripts/aiida_submit_ext_scheme.py @@ -0,0 +1,57 @@ +import argparse +import sys + +import yaml +from aiida import load_profile +from aiida.engine import submit +from aiida.plugins import DataFactory +from mpds_aiida.workflows.mpds import MPDSStructureWorkChain + + +def main(): + load_profile() + + parser = argparse.ArgumentParser(description="Submit an MPDSStructureWorkChain job") + parser.add_argument("phase", + nargs="?", + default="MgO/225", + help="Phase information in the format 'formula/sgs/pearson'") + parser.add_argument("--scheme", default=None, help="Full path to the scheme file") + args = parser.parse_args() + + phase = args.phase.split("/") + + if len(phase) == 3: + formula, sgs, pearson = phase + else: + formula, sgs, pearson = phase[0], phase[1], None + + try: + sgs = int(sgs) + except ValueError: + print(f"Error: space group should be an integer, got {sgs}") + sys.exit(1) + + inputs = MPDSStructureWorkChain.get_builder() + + if args.scheme: + try: + with open(args.scheme) as f: + inputs.workchain_options = yaml.safe_load(f) + except FileNotFoundError: + print(f"Error: Scheme file {args.scheme} not found") + sys.exit(1) + except yaml.YAMLError as exc: + print(f"Error parsing YAML file: {exc}") + sys.exit(1) + else: + inputs.workchain_options = {} + + inputs.metadata = {"label": "/".join(phase)} + inputs.mpds_query = DataFactory('dict')(dict={'formulae': formula, 'sgs': sgs}) + calc = submit(MPDSStructureWorkChain, **inputs) + print(f"Submitted WorkChain; calc=WorkCalculation(PK={calc.pk})") + + +if __name__ == "__main__": + main()