diff --git a/aiida_cp2k/calculations/__init__.py b/aiida_cp2k/calculations/__init__.py index f6f928c0..016a4212 100644 --- a/aiida_cp2k/calculations/__init__.py +++ b/aiida_cp2k/calculations/__init__.py @@ -6,6 +6,7 @@ ############################################################################### """AiiDA-CP2K input plugin.""" +import json from operator import add import numpy as np @@ -13,6 +14,7 @@ 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 ( @@ -28,6 +30,7 @@ StructureData = DataFactory("core.structure") TrajectoryData = DataFactory("core.array.trajectory") KpointsData = DataFactory("core.array.kpoints") +UpfData = DataFactory("pseudo.upf") class Cp2kCalculation(CalcJob): @@ -118,6 +121,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", @@ -311,6 +322,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/conftest.py b/conftest.py index d724d92a..db0e5174 100644 --- a/conftest.py +++ b/conftest.py @@ -1,5 +1,7 @@ """For pytest initialise a test database and profile.""" +import subprocess + import pytest pytest_plugins = ["aiida.manage.tests.pytest_fixtures"] @@ -31,3 +33,21 @@ def pytest_unconfigure(config): import sys del sys._called_from_test + + +@pytest.fixture(scope="function", autouse=True) +def setup_sssp_pseudos(aiida_profile): + """Create an SSSP pseudo potential family from scratch.""" + subprocess.run( + [ + "aiida-pseudo", + "install", + "sssp", + "-p", + "efficiency", + "-x", + "PBE", + "-v", + "1.3", + ] + ) diff --git a/examples/files/si.xyz b/examples/files/si.xyz new file mode 100644 index 00000000..f1a8e4ba --- /dev/null +++ b/examples/files/si.xyz @@ -0,0 +1,4 @@ +2 +Lattice="3.81196 0.0 0.0 1.9059800000000005 3.3012541982101284 0.0 1.9059800000000005 1.100418066070043 3.112452306633254" Properties=species:S:1:pos:R:3:_aiidalab_viewer_representation_default:I:1 spacegroup="P 1" unit_cell=conventional pbc="T T T" +Si 0.00000000 0.00000000 0.00000000 0 +Si 1.90598000 1.10041807 0.77811308 0 diff --git a/examples/single_calculations/example_sirius.py b/examples/single_calculations/example_sirius.py new file mode 100644 index 00000000..66abbba3 --- /dev/null +++ b/examples/single_calculations/example_sirius.py @@ -0,0 +1,127 @@ +############################################################################### +# 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, setup_sssp_pseudos): + """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": 5, + "PW_CUTOFF": 20, + "ENERGY_TOL": 0.1, + "DENSITY_TOL": 0.1, + "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, setup_sssp_pseudos=None) + + +if __name__ == "__main__": + cli() diff --git a/pyproject.toml b/pyproject.toml index bb200c64..cc36cd50 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]]