Skip to content

Commit

Permalink
Changes to make STM workchain work for bulk systems + add tests
Browse files Browse the repository at this point in the history
  • Loading branch information
PhilippRue committed Nov 25, 2024
1 parent 0b56724 commit 9ea6d04
Show file tree
Hide file tree
Showing 6 changed files with 118 additions and 45 deletions.
43 changes: 18 additions & 25 deletions aiida_kkr/tools/tools_STM_scan.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
__copyright__ = (u'Copyright (c), 2023, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.1.3'
__version__ = '0.1.4'

Check warning on line 16 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L16

Added line #L16 was not covered by tests
__contributors__ = (u'Philipp Rüßmann', u'Raffaele Aliberti')

##############################################################################
Expand Down Expand Up @@ -279,12 +279,15 @@ def STM_pathfinder(host_remote):
py_struc = supp_struc.get_pymatgen()

Check warning on line 279 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L279

Added line #L279 was not covered by tests

struc_dict = py_struc.as_dict()

Check warning on line 281 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L281

Added line #L281 was not covered by tests
# Find the Bravais vectors that are in plane vectors
# Find the Bravais vectors that are in-plane vectors (assumes 2D structure)
plane_vectors = {'plane_vectors': [], 'space_group': ''}
for vec in struc_dict['lattice']['matrix']:

Check warning on line 284 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L283-L284

Added lines #L283 - L284 were not covered by tests
# Is this sufficient to find all the in-plane vectors?
if vec[2] == 0:
if vec[2] == 0 or (struc.pbc[2] and (vec[0] + vec[1]) > 0):
plane_vectors['plane_vectors'].append(vec[:2])

Check warning on line 287 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L286-L287

Added lines #L286 - L287 were not covered by tests
# finally check if setting of plane_vectors worked
if 'plane_vectors' not in plane_vectors:
raise ValueError('Could not set "plane_vectors" in STM_pathfinder')

Check warning on line 290 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L289-L290

Added lines #L289 - L290 were not covered by tests

# Here we get the symmetry operations that are possible
symmetry_matrices = SpacegroupAnalyzer(py_struc).get_point_group_operations(cartesian=True)

Check warning on line 293 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L293

Added line #L293 was not covered by tests
Expand Down Expand Up @@ -493,28 +496,18 @@ def find_linear_combination_coefficients(plane_vectors, vectors):

# Formulate the system of equations Ax = b
A = np.vstack((plane_vectors[0], plane_vectors[1])).T

Check warning on line 498 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L498

Added line #L498 was not covered by tests

# Solve the system of equations using least squares method
data = []
for element in vectors:
b = element
# We use the least square mean error procedure to evaulate the units of da and db
# lstsq returns: coeff, residue, rank, and singular value
# We only need the coefficient.
data.append(np.linalg.lstsq(A, b, rcond=None))

# inverse of A matrix
Ainv = np.matrix(A)**(-1)

Check warning on line 500 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L500

Added line #L500 was not covered by tests
indices = []
for element in data:
supp = []
for elem in element[0]:
# Here we round to an integer, this is because of the numerical error
# which is present inside the calculation.
supp.append(round(elem))
indices.append(supp)

# Before returning the indices, we reorder them first from the lowest to the highest valued
# on the x axis and then from the lowest to the highest on the y axis.

indices = sorted(indices, key=itemgetter(0, 1))
# loop over flattened list
for vec in np.array(vectors).reshape(-1, 2):

Check warning on line 503 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L503

Added line #L503 was not covered by tests
# get indices from x = A^{-1}.b
index = np.array((Ainv * np.matrix(vec).transpose()).transpose()).reshape(2)
indices.append(index)

Check warning on line 506 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L505-L506

Added lines #L505 - L506 were not covered by tests
# make sure to have integer values
indices = np.round(np.array(indices), 0)

Check warning on line 508 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L508

Added line #L508 was not covered by tests

isort = indices[:, 0] + indices[:, 1] / (10 * max(indices[:, 0]))
indices = indices[isort.argsort()]

Check warning on line 511 in aiida_kkr/tools/tools_STM_scan.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/tools/tools_STM_scan.py#L510-L511

Added lines #L510 - L511 were not covered by tests

return indices
37 changes: 18 additions & 19 deletions aiida_kkr/workflows/kkr_STM.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
__copyright__ = (u'Copyright (c), 2024, Forschungszentrum Jülich GmbH, '
'IAS-1/PGI-1, Germany. All rights reserved.')
__license__ = 'MIT license, see LICENSE.txt file'
__version__ = '0.1.4'
__version__ = '0.1.5'
__contributors__ = (u'Raffaele Aliberti', u'David Antognini Silva', u'Philipp Rüßmann')
_VERBOSE_ = False

Expand Down Expand Up @@ -72,6 +72,18 @@ class kkr_STM_wc(WorkChain):
# add defaults of dos_params since they are passed onto that workflow
_wf_default['dos_params'] = kkr_imp_dos_wc.get_wf_defaults()['dos_params']

# return default values (helpful for users)
@classmethod
def get_wf_defaults(cls, silent=False):
"""Print and return _wf_default dictionary.
Can be used to easily create set of wf_parameters.
returns _wf_default, _options_default
"""
if not silent:
print(f'Version of workflow: {cls._wf_version}')
return cls._wf_default

Check warning on line 85 in aiida_kkr/workflows/kkr_STM.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/workflows/kkr_STM.py#L83-L85

Added lines #L83 - L85 were not covered by tests

@classmethod
def define(cls, spec):
"""
Expand Down Expand Up @@ -118,13 +130,6 @@ def define(cls, spec):
required=True,
help='Information of the impurity like position in the unit cell, screening cluster, atom type.'
)
spec.input(
'host_calc',
valid_type=RemoteData,
required=False,
help='The information about the clean host structure is required in order to continue the cluster'
'Inside a bigger host structure with empty sites.'
)
spec.input(
'host_remote',
valid_type=RemoteData,
Expand All @@ -137,12 +142,6 @@ def define(cls, spec):
required=True,
help='Impurity potential node',
)
spec.input(
'remote_data',
valid_type=RemoteData,
required=False,
help='Remote data from a converged kkr calculation, required for the gf writeout step',
)
spec.input(
'kkrflex_files',
valid_type=RemoteData,
Expand Down Expand Up @@ -373,16 +372,16 @@ def impurity_cluster_evaluation(self):
impurity_info_aux = impurity_info
imp_potential_node_aux = imp_potential_node

Check warning on line 373 in aiida_kkr/workflows/kkr_STM.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/workflows/kkr_STM.py#L372-L373

Added lines #L372 - L373 were not covered by tests

# Case in which we don't pass any element to embed in the impurity cluster, it
# uses the impurity files given in the inputs.
if len(coeff) == 0:
return impurity_info, imp_potential_node

Check warning on line 378 in aiida_kkr/workflows/kkr_STM.py

View check run for this annotation

Codecov / codecov/patch

aiida_kkr/workflows/kkr_STM.py#L377-L378

Added lines #L377 - L378 were not covered by tests

for element in coeff:

if _VERBOSE_:
t0 = time()

# Case in which we don't pass any element to embed in the impurity cluster, it
# uses the impurity files given in the inputs.
if element == []:
return impurity_info, imp_potential_node

# Check if the position is already in the cluster
# for this we need to first get the position
tmp_pos = self.get_tip_position_dict(element[0], element[1])
Expand Down
1 change: 0 additions & 1 deletion aiida_kkr/workflows/kkr_scf.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,7 +162,6 @@ class kkr_scf_wc(WorkChain):
_options_default.custom_scheduler_commands = '' # some additional scheduler commands

# intended to guide user interactively in setting up a valid wf_params node

@classmethod
def get_wf_defaults(cls, silent=False):
"""Print and return _wf_default dictionary.
Expand Down
Binary file added tests/data_dir/stm.aiida
Binary file not shown.
82 changes: 82 additions & 0 deletions tests/workflows/test_stm.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
#!/usr/bin/env python

import pytest
from ..dbsetup import *
from aiida.engine import run_get_node
from ..conftest import voronoi_local_code, kkrhost_local_code, test_dir, data_dir, import_with_migration

Check warning on line 6 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L3-L6

Added lines #L3 - L6 were not covered by tests


@pytest.mark.timeout(900, method='thread')
def test_stm_wc(

Check warning on line 10 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L9-L10

Added lines #L9 - L10 were not covered by tests
clear_database_before_test, voronoi_local_code, kkrhost_local_code, kkrimp_local_code, enable_archive_cache,
ndarrays_regression
):
"""
STM workflow test for a simple Cu host in host impurity adding a minimal scanning region
"""
from aiida.orm import Code, load_node, Dict, StructureData, load_group
from masci_tools.io.kkr_params import kkrparams
from aiida_kkr.workflows import kkr_STM_wc
from numpy import array

Check warning on line 20 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L17-L20

Added lines #L17 - L20 were not covered by tests

options = {

Check warning on line 22 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L22

Added line #L22 was not covered by tests
'queue_name': queuename,
'resources': {
'num_machines': 1
},
'max_wallclock_seconds': 5 * 60,
'withmpi': False,
'custom_scheduler_commands': ''
}
options = Dict(options)

Check warning on line 31 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L31

Added line #L31 was not covered by tests

# import parent calculation (converged host system)
group_pk = import_with_migration('data_dir/kkrimp_full_wc.aiida')
kkr_imp_scf = [n for n in load_group(group_pk).nodes if n.label == 'kkrimp_scf full Cu host_in_host'][0]

Check warning on line 35 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L34-L35

Added lines #L34 - L35 were not covered by tests

# create process builder to set parameters
builder = kkr_STM_wc.get_builder()
builder.metadata.label = 'stm test'
builder.kkrimp = kkrimp_local_code
builder.voronoi = voronoi_local_code
builder.kkr = kkrhost_local_code
builder.options = options

Check warning on line 43 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L38-L43

Added lines #L38 - L43 were not covered by tests

builder.host_remote = kkr_imp_scf.inputs.remote_data_host
builder.imp_info = kkr_imp_scf.inputs.impurity_info
builder.imp_potential_node = kkr_imp_scf.outputs.converged_potential

Check warning on line 47 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L45-L47

Added lines #L45 - L47 were not covered by tests

builder.tip_position = Dict({'ilayer': 0, 'nx': 2, 'ny': 2})

Check warning on line 49 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L49

Added line #L49 was not covered by tests

builder.wf_parameters = Dict({

Check warning on line 51 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L51

Added line #L51 was not covered by tests
'jij_run': False,
'lmdos': True,
'retrieve_kkrflex': True,
'dos_params': {
'nepts': 7,
'tempr': 200.0,
'emin': -1.0,
'emax': 1.0,
'kmesh': [5, 5, 5]
}
})

# now run calculation
with enable_archive_cache(data_dir / 'stm.aiida'):
out, node = run_get_node(builder)
print(out)
print(list(node.called))

Check warning on line 68 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L65-L68

Added lines #L65 - L68 were not covered by tests

# check outcome
assert 'STM_dos_data_lmdos' in out

Check warning on line 71 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L71

Added line #L71 was not covered by tests

# check dos data
check_dict = {

Check warning on line 74 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L74

Added line #L74 was not covered by tests
'x': out['STM_dos_data_lmdos'].get_x()[1],
'y': out['STM_dos_data_lmdos'].get_y()[5][1],
}
print(check_dict)
ndarrays_regression.check(check_dict)

Check warning on line 79 in tests/workflows/test_stm.py

View check run for this annotation

Codecov / codecov/patch

tests/workflows/test_stm.py#L78-L79

Added lines #L78 - L79 were not covered by tests

# print('x', out['STM_dos_data_lmdos'].get_x()[1])
# print('y', out['STM_dos_data_lmdos'].get_y()[5][1])
Binary file added tests/workflows/test_stm/test_stm_wc.npz
Binary file not shown.

0 comments on commit 9ea6d04

Please sign in to comment.