Skip to content

Commit

Permalink
Fix HoppingMatrix with new schema (#61)
Browse files Browse the repository at this point in the history
* Added HoppingMatrix, CrystalFieldSplitting to properties

Added WignerSeitz to variables

Removed common.py module

* Added HoppingMatrix and CrystalFieldSplittings to Outputs list of properties

* Added testing

* Added todo in HoppingMatrix
  • Loading branch information
JosePizarro3 authored Apr 30, 2024
1 parent a7412b2 commit efceab6
Show file tree
Hide file tree
Showing 6 changed files with 210 additions and 75 deletions.
74 changes: 0 additions & 74 deletions src/nomad_simulations/common.py

This file was deleted.

10 changes: 9 additions & 1 deletion src/nomad_simulations/outputs.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,11 @@
from .physical_property import PhysicalProperty
from .numerical_settings import SelfConsistency
from .properties import (
ElectronicBandGap,
FermiLevel,
ChemicalPotential,
CrystalFieldSplitting,
HoppingMatrix,
ElectronicBandGap,
ElectronicDensityOfStates,
XASSpectra,
)
Expand Down Expand Up @@ -65,6 +67,12 @@ class Outputs(ArchiveSection):

chemical_potential = SubSection(sub_section=ChemicalPotential.m_def, repeats=True)

crystal_field_splitting = SubSection(
sub_section=CrystalFieldSplitting.m_def, repeats=True
)

hopping_matrix = SubSection(sub_section=HoppingMatrix.m_def, repeats=True)

electronic_band_gap = SubSection(sub_section=ElectronicBandGap.m_def, repeats=True)

electronic_dos = SubSection(
Expand Down
1 change: 1 addition & 0 deletions src/nomad_simulations/properties/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,4 @@
ElectronicDensityOfStates,
XASSpectra,
)
from .hopping_matrix import HoppingMatrix, CrystalFieldSplitting
106 changes: 106 additions & 0 deletions src/nomad_simulations/properties/hopping_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
#
# Copyright The NOMAD Authors.
#
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import numpy as np

from nomad.metainfo import Quantity, Section, Context

from ..physical_property import PhysicalProperty


class HoppingMatrix(PhysicalProperty):
"""
Transition probability between two atomic orbitals in a tight-binding model.
"""

iri = 'http://fairmat-nfdi.eu/taxonomy/HoppingMatrix'

n_orbitals = Quantity(
type=np.int32,
description="""
Number of orbitals in the tight-binding model.
""",
)

degeneracy_factors = Quantity(
type=np.int32,
shape=['*'],
description="""
Degeneracy of each Wigner-Seitz point.
""",
)

value = Quantity(
type=np.complex128,
unit='joule',
description="""
Value of the hopping matrix in joules. The elements are complex numbers defined for each Wigner-Seitz point and
each pair of orbitals; thus, `rank = [n_orbitals, n_orbitals]`. Note this contains also the onsite values, i.e.,
it includes the Wigner-Seitz point (0, 0, 0), hence the `CrystalFieldSplitting` values.
""",
)

def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
# ! n_orbitals need to be set up during initialization of the class
self.rank = (
[] if self.n_orbitals is None else [self.n_orbitals, self.n_orbitals]
)
self.name = self.m_def.name

# TODO add normalization to extract DOS, band structure, etc, properties from `HoppingMatrix`

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)


class CrystalFieldSplitting(PhysicalProperty):
"""
Energy difference between the degenerated orbitals of an ion in a crystal field environment.
"""

iri = 'http://fairmat-nfdi.eu/taxonomy/CrystalFieldSplitting'

n_orbitals = Quantity(
type=np.int32,
description="""
Number of orbitals in the tight-binding model.
""",
)

value = Quantity(
type=np.float64,
unit='joule',
description="""
Value of the crystal field splittings in joules. This is the intra-orbital local contribution, i.e., the same orbital
at the same Wigner-Seitz point (0, 0, 0).
""",
)

def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
# ! n_orbitals need to be set up during initialization of the class
self.rank = [] if self.n_orbitals is None else [self.n_orbitals]
self.name = self.m_def.name

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
24 changes: 24 additions & 0 deletions src/nomad_simulations/variables.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,3 +129,27 @@ def __init__(

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)


class WignerSeitz(Variables):
"""
Wigner-Seitz points in which the real space is discretized. This variable is used to define `HoppingMatrix(PhysicalProperty)` and
other inter-cell properties. See, e.g., https://en.wikipedia.org/wiki/Wigner–Seitz_cell.
"""

grid_points = Quantity(
type=np.float64,
shape=['n_grid_points', 3],
description="""
Wigner-Seitz points with respect to the origin cell, (0, 0, 0). These are 3D arrays stored in fractional coordinates.
""",
)

def __init__(
self, m_def: Section = None, m_context: Context = None, **kwargs
) -> None:
super().__init__(m_def, m_context, **kwargs)
self.name = self.m_def.name

def normalize(self, archive, logger) -> None:
super().normalize(archive, logger)
70 changes: 70 additions & 0 deletions tests/test_hopping_matrix.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
#
# Copyright The NOMAD Authors.
#
# This file is part of NOMAD. See https://nomad-lab.eu for further info.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

import pytest
import numpy as np

from nomad_simulations.properties import HoppingMatrix, CrystalFieldSplitting


class TestHoppingMatrix:
"""
Test the `HoppingMatrix` class defined in `properties/hopping_matrix.py`.
"""

# ! Include this initial `test_default_quantities` method when testing your PhysicalProperty classes
@pytest.mark.parametrize(
'n_orbitals, rank',
[
(None, []),
(3, [3, 3]),
],
)
def test_default_quantities(self, n_orbitals: int, rank: list):
"""
Test the default quantities assigned when creating an instance of the `HoppingMatrix` class.
"""
hopping_matrix = HoppingMatrix(n_orbitals=n_orbitals)
assert hopping_matrix.iri == 'http://fairmat-nfdi.eu/taxonomy/HoppingMatrix'
assert hopping_matrix.name == 'HoppingMatrix'
assert hopping_matrix.rank == rank


class TestCrystalFieldSplitting:
"""
Test the `CrystalFieldSplitting` class defined in `properties/hopping_matrix.py`.
"""

# ! Include this initial `test_default_quantities` method when testing your PhysicalProperty classes
@pytest.mark.parametrize(
'n_orbitals, rank',
[
(None, []),
(3, [3]),
],
)
def test_default_quantities(self, n_orbitals: int, rank: list):
"""
Test the default quantities assigned when creating an instance of the `CrystalFieldSplitting` class.
"""
crystal_field = CrystalFieldSplitting(n_orbitals=n_orbitals)
assert (
crystal_field.iri == 'http://fairmat-nfdi.eu/taxonomy/CrystalFieldSplitting'
)
assert crystal_field.name == 'CrystalFieldSplitting'
assert crystal_field.rank == rank

0 comments on commit efceab6

Please sign in to comment.