From bcd9456bff7192f3c72528e4e27e97fc00235372 Mon Sep 17 00:00:00 2001 From: Daniel Pozsar Date: Tue, 22 Oct 2024 12:56:01 +0200 Subject: [PATCH] cleared up repository --- .gitignore | 6 ++ .pre-commit-config.yaml | 22 +++--- README.md | 12 +++ docs/requirements.txt | 1 - pyproject.toml | 7 +- requirements-dev.txt | 5 +- requirements.txt | 8 +- src/grogu/__init__.py | 3 - src/grogu/useful.py | 168 ++++++++++++++++++++++++---------------- tests/test_useful.py | 24 +++++- 10 files changed, 160 insertions(+), 96 deletions(-) diff --git a/.gitignore b/.gitignore index 7c038d8..fb3d223 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,7 @@ dist # VSCode settings .vscode +.venv .conda .pytest_cache @@ -19,3 +20,8 @@ docs/source/api/generated # Debug tmp* +.coverage +test.ipynb + +# Mac stuff +*.DS_Store* diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8969772..b5a049d 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,15 +1,15 @@ # See https://pre-commit.com for more information # See https://pre-commit.com/hooks.html for more hooks repos: -- repo: https://github.com/adrybakov/pre-commit-hooks - rev: 0.2.0 - hooks: - - id: license-headers - args: - - --license-file - - L-HEADER - - --update-year - - --verbose +#- repo: https://github.com/adrybakov/pre-commit-hooks +# rev: 0.2.0 +# hooks: +# - id: license-headers +# args: +# - --license-file +# - L-HEADER +# - --update-year +# - --verbose - repo: https://github.com/pre-commit/pre-commit-hooks rev: v4.6.0 hooks: @@ -26,12 +26,12 @@ repos: rev: 24.4.2 hooks: - id: black - language_version: python3.11 + language_version: python3.12 - repo: local hooks: - id: pytest-check name: pytest-check - entry: pytest + entry: ./.venv/bin/pytest language: system pass_filenames: false always_run: true diff --git a/README.md b/README.md index 5e1a4b7..e48c6b1 100644 --- a/README.md +++ b/README.md @@ -1 +1,13 @@ # Relativistic magnetic interactions from non-orthogonal basis sets + +# TODO + +- Definition of magnetic entities: + * Through simple sequence o forbitals in the unit cell + * Through atom specification + * Through atom and orbital specification +- Separation of TR and TRB components of the Hamiltonian, Identification of the exchange field. +- Definition of commutator expressions, old projection matrix elements +- Efficient calculation of Green's functions +- Calculation of energy and momentum resolved derivatives +- Parallel BZ and serial energy integral \ No newline at end of file diff --git a/docs/requirements.txt b/docs/requirements.txt index 1422923..7eb2584 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,3 @@ sphinx sphinx_rtd_theme numpydoc -doctest diff --git a/pyproject.toml b/pyproject.toml index 34f0312..ef660d3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -21,6 +21,7 @@ dependencies = [ "numpy", "scipy", "sisl", + "openmpi", "mpi4py", "argparse", ] @@ -43,11 +44,11 @@ Repository = "https://github.com/me/spam.git" Issues = "https://github.com/pypa/sampleproject/issues" [tool.pytest.ini_options] +pythonpath = [ + "src/grogu/" +] addopts = [ "--import-mode=importlib", # "--cov", "--doctest-modules", ] -pythonpath = [ - "src/grogu/", -] diff --git a/requirements-dev.txt b/requirements-dev.txt index a9edffa..fb661ad 100644 --- a/requirements-dev.txt +++ b/requirements-dev.txt @@ -6,13 +6,12 @@ twine # code-linters black -license-headers +#license-headers # dev-tools pre-commit pytest pytest-randomly pytest-cov -doctest +isort sphinx -git diff --git a/requirements.txt b/requirements.txt index 539e9e5..64f3332 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,6 +1,8 @@ # Package dependencies -numpy -scipy +argparse +numpy>=1.13 +scipy>=0.18 sisl +netcdf4 +openmpi mpi4py -argparse diff --git a/src/grogu/__init__.py b/src/grogu/__init__.py index 39a4a19..93d0ca4 100644 --- a/src/grogu/__init__.py +++ b/src/grogu/__init__.py @@ -17,6 +17,3 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. - -from jij import * -from useful import * diff --git a/src/grogu/useful.py b/src/grogu/useful.py index a898a7e..df49241 100644 --- a/src/grogu/useful.py +++ b/src/grogu/useful.py @@ -23,23 +23,7 @@ from itertools import permutations, product import numpy as np from scipy.special import roots_legendre - # define some useful functions -def hsk(dh, k=(0, 0, 0)): - """ - One way to speed up Hk and Sk generation - """ - k = np.asarray(k, np.float64) # this two conversion lines - k.shape = (-1,) # are from the sisl source - - # this generates the list of phases - phases = np.exp(-1j * np.dot(np.dot(np.dot(dh.rcell, k), dh.cell), dh.sc.sc_off.T)) - - HKU = np.einsum("abc,c->ab", dh.hup, phases) - HKD = np.einsum("abc,c->ab", dh.hdo, phases) - SK = np.einsum("abc,c->ab", dh.sov, phases) - - return HKU, HKD, SK def make_contour(emin=-20, emax=0.0, enum=42, p=150): @@ -96,72 +80,120 @@ def make_kset(dirs="xyz", NUMK=20): return kset -def make_atran(nauc, dirs="xyz", dist=1): - """ - Simple pair generator. Depending on the value of the dirs - argument sampling in 1,2 or 3 dimensions is generated. - If dirs argument does not contain either of x,y or z - a single pair is returend. - """ - if not (sum([d in dirs for d in "xyz"])): - return (0, 0, [1, 0, 0]) +# Pauli matrices +tau_x = np.array([[0, 1], [1, 0]]) +tau_y = np.array([[0, -1j], [1j, 0]]) +tau_z = np.array([[1, 0], [0, -1]]) +tau_0 = np.array([[1, 0], [0, 1]]) - dran = len(dirs) * [np.arange(-dist, dist + 1)] - mg = np.meshgrid(*dran) - dirsdict = dict() - for d in enumerate(dirs): - dirsdict[d[1]] = mg[d[0]].flatten() - for d in "xyz": - if not (d in dirs): - dirsdict[d] = 0 * dirsdict[dirs[0]] +def comm(a, b): + "Shorthand for commutator" + return a @ b - b @ a - ucran = np.array([dirsdict[d] for d in "xyz"]).T - atran = [] - for i, j in list(product(range(nauc), repeat=2)): - for u in ucran: - if (abs(i - j) + sum(abs(u))) > 0: - atran.append((i, j, list(u))) - return atran +def tau_u(u): + """ + Pauli matrix in direction u. + """ + u = u / np.linalg.norm(u) # u is force to be of unit length + return u[0] * tau_x + u[1] * tau_y + u[2] * tau_z -def add(x, y): - """The sum of two numbers for testing. +# +def crossM(u): + """ + Definition for the cross-product matrix. + Acting as a crossproduct with vector u. + """ + return np.array([[0, -u[2], u[1]], [u[2], 0, -u[0]], [-u[1], u[0], 0]]) - This function adds to numbers together. I only created this for testing documentation and examples. - Parameters - ---------- - x : float - First number - y : float - Second number added to `x` +def RotM(theta, u, eps=1e-10): + """ + Definition of rotation matrix with angle theta around direction u. + """ + u = u / np.linalg.norm(u) - Returns - ------- - sum : int - The sum of the inputs + M = ( + np.cos(theta) * np.eye(3) + + np.sin(theta) * crossM(u) + + (1 - np.cos(theta)) * np.outer(u, u) + ) + M[abs(M) < eps] = 0.0 # kill off small numbers + return M - See Also - -------- - numpy.add : Adds more than two numbers. - Notes - ----- - We can create some latex notes here [1]_ : +def RotMa2b(a, b, eps=1e-10): + """ + Definition of rotation matrix rotating unit vector a to unit vector b. + Function returns array R such that R@a = b holds. + """ + v = np.cross(a, b) + c = a @ b + M = np.eye(3) + crossM(v) + crossM(v) @ crossM(v) / (1 + c) + M[abs(M) < eps] = 0.0 # kill off small numbers + return M + - .. math:: a + b = c +def spin_tracer(M): + """ + Spin tracer utility. + This akes an operator with the orbital-spin sequence: + orbital 1 up, + orbital 1 down, + orbital 2 up, + orbital 2 down, + that is in the SPIN-BOX representation, + and extracts orbital dependent Pauli traces. + """ - References - ---------- - .. [1] https://numpydoc.readthedocs.io/en/latest/format.html + M11 = M[0::2, 0::2] + M12 = M[0::2, 1::2] + M21 = M[1::2, 0::2] + M22 = M[1::2, 1::2] + M_o = dict() + M_o["x"] = M12 + M21 + M_o["y"] = 1j * (M12 - M21) + M_o["z"] = M11 - M22 + M_o["c"] = M11 + M22 + return M_o - Examples - -------- - >>> add(1, 2) - 3 +def parse_magnetic_entity(dh, atom=None, l=None, **kwargs): + """ + Function to define orbital indeces of a given magnetic entity. + dh: a sisl Hamiltonian object + atom: an integer or list of integers, defining atom (or atoms) in the unicell forming the magnetic entity + l: integer, defining the angular momentum channel + """ + # case where we deal with more than one atom defining the magnetic entity + if type(atom) == list: + dat = [] + for a in atom: + a_orb_idx = dh.geometry.a2o(a, all=True) + if ( + type(l) == int + ): # if specified we restrict to given l angular momentum channel inside each atom + a_orb_idx = a_orb_idx[[o.l == l for o in dh.geometry.atoms[a].orbitals]] + dat.append(a_orb_idx) + orbital_indeces = np.hstack(dat) + # case where we deal with a singel atom magnetic entity + elif type(atom) == int: + orbital_indeces = dh.geometry.a2o(atom, all=True) + if ( + type(l) == int + ): # if specified we restrict to given l angular momentum channel + orbital_indeces = orbital_indeces[ + [o.l == l for o in dh.geometry.atoms[atom].orbitals] + ] + + return orbital_indeces # numpy array containing integers labeling orbitals associated to a magnetic entity. + + +def blow_up_orbindx(orb_indices): + """ + Function to blow up orbital indeces to make SPIN BOX indices. """ - return x + y + return np.array([[2 * o, 2 * o + 1] for o in orb_indices]).flatten() diff --git a/tests/test_useful.py b/tests/test_useful.py index 56c5d99..ff3a2ab 100644 --- a/tests/test_useful.py +++ b/tests/test_useful.py @@ -19,11 +19,27 @@ # SOFTWARE. import pytest -from useful import add +from useful import * @pytest.mark.parametrize( - "a, b, c, expected_out", [(1, 2, 3, True), (6, 7, 13, True), (1, 2, 10, False)] + "a, b, c", + [ + (tau_x, tau_y, tau_z), + (tau_z, tau_x, tau_y), + (tau_y, tau_z, tau_x), + (tau_z, tau_y, -tau_x), + ], ) -def test_add(a, b, c, expected_out): - assert (add(a, b) == c) == expected_out +def test_comm(a, b, c): + assert (comm(a, b) == 2j * c).all() + + +@pytest.mark.parametrize( + "dirs, NUMK, out", + [ + ("", 10, np.array([[0, 0, 0]])), + ], +) +def test_make_kset(dirs, NUMK, out): + assert (make_kset(dirs, NUMK) == out).all()