Skip to content

Commit 4354b0a

Browse files
authored
Add UpfData input namespace (#194)
- Add aiida-pseudo dependency. - Install SSSP/1.3/PBE/efficiency pseudo using aiida-sssp. - Add an example run. - Add setup_sssp_pseudos fixture.
1 parent 5d10ef7 commit 4354b0a

File tree

5 files changed

+170
-0
lines changed

5 files changed

+170
-0
lines changed

aiida_cp2k/calculations/__init__.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,15 @@
66
###############################################################################
77
"""AiiDA-CP2K input plugin."""
88

9+
import json
910
from operator import add
1011

1112
import numpy as np
1213
from aiida.common import CalcInfo, CodeInfo, InputValidationError
1314
from aiida.engine import CalcJob
1415
from aiida.orm import Dict, RemoteData, SinglefileData
1516
from aiida.plugins import DataFactory
17+
from upf_to_json import upf_to_json
1618

1719
from ..utils import Cp2kInput
1820
from ..utils.datatype_helpers import (
@@ -28,6 +30,7 @@
2830
StructureData = DataFactory("core.structure")
2931
TrajectoryData = DataFactory("core.array.trajectory")
3032
KpointsData = DataFactory("core.array.kpoints")
33+
UpfData = DataFactory("pseudo.upf")
3134

3235

3336
class Cp2kCalculation(CalcJob):
@@ -118,6 +121,14 @@ def define(cls, spec):
118121
),
119122
)
120123

124+
spec.input_namespace(
125+
"pseudos_upf",
126+
valid_type=UpfData,
127+
dynamic=True,
128+
required=True,
129+
help="A mapping of `UpfData` nodes onto the kind name to which they should apply.",
130+
)
131+
121132
# Specify default parser.
122133
spec.input(
123134
"metadata.options.parser_name",
@@ -316,6 +327,12 @@ def prepare_for_submission(self, folder):
316327
)
317328
write_pseudos(inp, self.inputs.pseudos, folder)
318329

330+
if "pseudos_upf" in self.inputs:
331+
for atom_kind, pseudo in self.inputs.pseudos_upf.items():
332+
pseudo_dict = upf_to_json(pseudo.get_content(), atom_kind)
333+
with folder.open(atom_kind + ".json", "w") as fobj:
334+
fobj.write(json.dumps(pseudo_dict, indent=2))
335+
319336
# Kpoints.
320337
if "kpoints" in self.inputs:
321338
try:

conftest.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
"""For pytest initialise a test database and profile."""
22

3+
import subprocess
4+
35
import pytest
46

57
pytest_plugins = ["aiida.manage.tests.pytest_fixtures"]
@@ -31,3 +33,21 @@ def pytest_unconfigure(config):
3133
import sys
3234

3335
del sys._called_from_test
36+
37+
38+
@pytest.fixture(scope="function", autouse=True)
39+
def setup_sssp_pseudos(aiida_profile):
40+
"""Create an SSSP pseudo potential family from scratch."""
41+
subprocess.run(
42+
[
43+
"aiida-pseudo",
44+
"install",
45+
"sssp",
46+
"-p",
47+
"efficiency",
48+
"-x",
49+
"PBE",
50+
"-v",
51+
"1.3",
52+
]
53+
)

examples/files/si.xyz

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2
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"
3+
Si 0.00000000 0.00000000 0.00000000 0
4+
Si 1.90598000 1.10041807 0.77811308 0
Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
###############################################################################
2+
# Copyright (c), The AiiDA-CP2K authors. #
3+
# SPDX-License-Identifier: MIT #
4+
# AiiDA-CP2K is hosted on GitHub at https://github.com/aiidateam/aiida-cp2k #
5+
# For further information on the license, see the LICENSE.txt file. #
6+
###############################################################################
7+
"""Run simple DFT with calculation with SIRIUS."""
8+
9+
import os
10+
import sys
11+
12+
import ase.io
13+
import click
14+
from aiida import common, engine, orm, plugins
15+
16+
StructureData = plugins.DataFactory("core.structure")
17+
18+
19+
def example_sirius(cp2k_code, setup_sssp_pseudos):
20+
"""Run simple DFT calculation."""
21+
22+
print("Testing CP2K SIRIUS ENERGY on Si (DFT)...")
23+
24+
thisdir = os.path.dirname(os.path.realpath(__file__))
25+
26+
# Structure.
27+
structure = StructureData(
28+
ase=ase.io.read(os.path.join(thisdir, "..", "files", "si.xyz"))
29+
)
30+
31+
# Parameters.
32+
parameters = orm.Dict(
33+
{
34+
"FORCE_EVAL": {
35+
"METHOD": "SIRIUS",
36+
"STRESS_TENSOR": "ANALYTICAL",
37+
"PRINT": {
38+
"FORCES": {"FILENAME": "requested-forces", "ADD_LAST": "SYMBOLIC"}
39+
},
40+
"PW_DFT": {
41+
"CONTROL": {"VERBOSITY": 2},
42+
"PARAMETERS": {
43+
"ELECTRONIC_STRUCTURE_METHOD": "pseudopotential",
44+
"USE_SYMMETRY": True,
45+
"GK_CUTOFF": 5,
46+
"PW_CUTOFF": 20,
47+
"ENERGY_TOL": 0.1,
48+
"DENSITY_TOL": 0.1,
49+
"NUM_DFT_ITER": 400,
50+
"SMEARING": "FERMI_DIRAC",
51+
"SMEARING_WIDTH": 0.00225,
52+
},
53+
"ITERATIVE_SOLVER": {
54+
"ENERGY_TOLERANCE": 0.001,
55+
"NUM_STEPS": 20,
56+
"SUBSPACE_SIZE": 4,
57+
"CONVERGE_BY_ENERGY": 1,
58+
},
59+
},
60+
"DFT": {
61+
"XC": {
62+
"XC_FUNCTIONAL": {
63+
"GGA_X_PBE": {"_": ""},
64+
"GGA_C_PBE": {"_": ""},
65+
}
66+
},
67+
"PRINT": {
68+
"MO": {
69+
"_": "OFF",
70+
"ADD_LAST": "SYMBOLIC",
71+
"EIGENVALUES": True,
72+
"OCCUPATION_NUMBERS": True,
73+
"NDIGITS": 12,
74+
"EACH": {"CELL_OPT": 0, "GEO_OPT": 0, "MD": 0, "QS_SCF": 0},
75+
},
76+
"MULLIKEN": {
77+
"_": "ON",
78+
"ADD_LAST": "SYMBOLIC",
79+
"EACH": {"CELL_OPT": 0, "GEO_OPT": 0, "MD": 0},
80+
},
81+
"LOWDIN": {"_": "OFF"},
82+
"HIRSHFELD": {"_": "OFF"},
83+
},
84+
},
85+
"SUBSYS": {
86+
"KIND": [
87+
{
88+
"_": "Si",
89+
"POTENTIAL": "UPF Si.json",
90+
},
91+
],
92+
},
93+
},
94+
}
95+
)
96+
97+
# Construct process builder.
98+
builder = cp2k_code.get_builder()
99+
builder.structure = structure
100+
builder.parameters = parameters
101+
builder.code = cp2k_code
102+
pseudo_family = orm.load_group("SSSP/1.3/PBE/efficiency")
103+
builder.pseudos_upf = pseudo_family.get_pseudos(structure=structure)
104+
builder.metadata.options.resources = {
105+
"num_machines": 1,
106+
"num_mpiprocs_per_machine": 1,
107+
}
108+
builder.metadata.options.max_wallclock_seconds = 1 * 3 * 60
109+
110+
print("Submitted calculation...")
111+
engine.run(builder)
112+
113+
114+
@click.command("cli")
115+
@click.argument("codelabel")
116+
def cli(codelabel):
117+
"""Click interface."""
118+
try:
119+
code = orm.load_code(codelabel)
120+
except common.NotExistent:
121+
print(f"The code '{codelabel}' does not exist.")
122+
sys.exit(1)
123+
example_sirius(code, setup_sssp_pseudos=None)
124+
125+
126+
if __name__ == "__main__":
127+
cli()

pyproject.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ dependencies = [
2525
"ase",
2626
"ruamel.yaml>=0.16.5",
2727
"cp2k-output-tools",
28+
"aiida-pseudo~=1.2",
29+
"upf-to-json>=0.9",
2830
]
2931

3032
[[project.authors]]

0 commit comments

Comments
 (0)