diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5b4dc74c..a949152c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,7 @@ jobs: export DOCKERID=`docker run -d aiida_cp2k_test` docker exec --tty $DOCKERID wait-for-services docker logs $DOCKERID + docker exec --tty --user aiida $DOCKERID /bin/bash -l -c 'aiida-pseudo install sssp -v 1.3 -x PBE -p efficiency' docker exec --tty --user aiida $DOCKERID /bin/bash -l -c 'cd /opt/aiida-cp2k/ && py.test --cov aiida_cp2k --cov-append .' diff --git a/aiida_cp2k/calculations/__init__.py b/aiida_cp2k/calculations/__init__.py index e495158c..756711fe 100644 --- a/aiida_cp2k/calculations/__init__.py +++ b/aiida_cp2k/calculations/__init__.py @@ -6,12 +6,14 @@ ############################################################################### """AiiDA-CP2K input plugin.""" +import json from operator import add from aiida.common import CalcInfo, CodeInfo, InputValidationError from aiida.engine import CalcJob from aiida.orm import Dict, RemoteData, SinglefileData from aiida.plugins import DataFactory +from upf_to_json import upf_to_json from ..utils import Cp2kInput from ..utils.datatype_helpers import ( @@ -26,7 +28,7 @@ BandsData = DataFactory("core.array.bands") StructureData = DataFactory("core.structure") KpointsData = DataFactory("core.array.kpoints") - +UpfData = DataFactory("pseudo.upf") class Cp2kCalculation(CalcJob): """This is a Cp2kCalculation, subclass of JobCalculation, to prepare input for an ab-initio CP2K calculation. @@ -105,6 +107,14 @@ def define(cls, spec): ), ) + spec.input_namespace( + "pseudos_upf", + valid_type=UpfData, + dynamic=True, + required=True, + help="A mapping of `UpfData` nodes onto the kind name to which they should apply.", + ) + # Specify default parser. spec.input( "metadata.options.parser_name", @@ -265,6 +275,12 @@ def prepare_for_submission(self, folder): ) write_pseudos(inp, self.inputs.pseudos, folder) + if "pseudos_upf" in self.inputs: + for atom_kind, pseudo in self.inputs.pseudos_upf.items(): + pseudo_dict = upf_to_json(pseudo.get_content(), atom_kind) + with folder.open(atom_kind + ".json", "w") as fobj: + fobj.write(json.dumps(pseudo_dict, indent=2)) + # Kpoints. if "kpoints" in self.inputs: try: diff --git a/examples/files/si.xyz b/examples/files/si.xyz new file mode 100644 index 00000000..f181bb8c --- /dev/null +++ b/examples/files/si.xyz @@ -0,0 +1,10 @@ +8 +Lattice="5.43 0.0 0.0 0.0 5.43 0.0 0.0 0.0 5.43" Properties=species:S:1:pos:R:3:spacegroup_kinds:I:1 spacegroup="F d -3 m" unit_cell=conventional pbc="T T T" +Si 0.00000000 0.00000000 0.00000000 0 +Si 0.00000000 2.71500000 2.71500000 0 +Si 2.71500000 2.71500000 0.00000000 0 +Si 2.71500000 0.00000000 2.71500000 0 +Si 4.07250000 1.35750000 4.07250000 0 +Si 1.35750000 1.35750000 1.35750000 0 +Si 1.35750000 4.07250000 4.07250000 0 +Si 4.07250000 4.07250000 1.35750000 0 diff --git a/examples/single_calculations/example_sirius.py b/examples/single_calculations/example_sirius.py new file mode 100644 index 00000000..3fb3af99 --- /dev/null +++ b/examples/single_calculations/example_sirius.py @@ -0,0 +1,126 @@ +############################################################################### +# Copyright (c), The AiiDA-CP2K authors. # +# SPDX-License-Identifier: MIT # +# AiiDA-CP2K is hosted on GitHub at https://github.com/aiidateam/aiida-cp2k # +# For further information on the license, see the LICENSE.txt file. # +############################################################################### +"""Run simple DFT with calculation with SIRIUS.""" + +import os +import sys + +import ase.io +import click +from aiida import common, engine, orm, plugins + +StructureData = plugins.DataFactory("core.structure") + + +def example_sirius(cp2k_code): + """Run simple DFT calculation.""" + + print("Testing CP2K SIRIUS ENERGY on Si (DFT)...") + + thisdir = os.path.dirname(os.path.realpath(__file__)) + + # Structure. + structure = StructureData( + ase=ase.io.read(os.path.join(thisdir, "..", "files", "si.xyz")) + ) + + # Parameters. + parameters = orm.Dict( + { + "FORCE_EVAL": { + "METHOD": "SIRIUS", + "STRESS_TENSOR": "ANALYTICAL", + "PRINT": { + "FORCES": {"FILENAME": "requested-forces", "ADD_LAST": "SYMBOLIC"} + }, + "PW_DFT": { + "CONTROL": {"VERBOSITY": 2}, + "PARAMETERS": { + "ELECTRONIC_STRUCTURE_METHOD": "pseudopotential", + "USE_SYMMETRY": True, + "GK_CUTOFF": 10, + "PW_CUTOFF": 55, + "ENERGY_TOL": 1e-15, + "NUM_DFT_ITER": 400, + "SMEARING": "FERMI_DIRAC", + "SMEARING_WIDTH": 0.00225, + }, + "ITERATIVE_SOLVER": { + "ENERGY_TOLERANCE": 0.001, + "NUM_STEPS": 20, + "SUBSPACE_SIZE": 4, + "CONVERGE_BY_ENERGY": 1, + }, + }, + "DFT": { + "XC": { + "XC_FUNCTIONAL": { + "GGA_X_PBE": {"_": ""}, + "GGA_C_PBE": {"_": ""}, + } + }, + "PRINT": { + "MO": { + "_": "OFF", + "ADD_LAST": "SYMBOLIC", + "EIGENVALUES": True, + "OCCUPATION_NUMBERS": True, + "NDIGITS": 12, + "EACH": {"CELL_OPT": 0, "GEO_OPT": 0, "MD": 0, "QS_SCF": 0}, + }, + "MULLIKEN": { + "_": "ON", + "ADD_LAST": "SYMBOLIC", + "EACH": {"CELL_OPT": 0, "GEO_OPT": 0, "MD": 0}, + }, + "LOWDIN": {"_": "OFF"}, + "HIRSHFELD": {"_": "OFF"}, + }, + }, + "SUBSYS": { + "KIND": [ + { + "_": "Si", + "POTENTIAL": "UPF Si.json", + }, + ], + }, + }, + } + ) + + # Construct process builder. + builder = cp2k_code.get_builder() + builder.structure = structure + builder.parameters = parameters + builder.code = cp2k_code + pseudo_family = orm.load_group("SSSP/1.3/PBE/efficiency") + builder.pseudos_upf = pseudo_family.get_pseudos(structure=structure) + builder.metadata.options.resources = { + "num_machines": 1, + "num_mpiprocs_per_machine": 1, + } + builder.metadata.options.max_wallclock_seconds = 1 * 3 * 60 + + print("Submitted calculation...") + engine.run(builder) + + +@click.command("cli") +@click.argument("codelabel") +def cli(codelabel): + """Click interface.""" + try: + code = orm.load_code(codelabel) + except common.NotExistent: + print(f"The code '{codelabel}' does not exist.") + sys.exit(1) + example_sirius(code) + + +if __name__ == "__main__": + cli() diff --git a/pyproject.toml b/pyproject.toml index 316ebce5..3e0fed67 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -25,6 +25,8 @@ dependencies = [ "ase", "ruamel.yaml>=0.16.5", "cp2k-output-tools", + "aiida-pseudo~=1.2", + "upf-to-json>=0.9", ] [[project.authors]]