Skip to content

Commit

Permalink
Merge pull request #2 from nomad-coe/magnetic_properties
Browse files Browse the repository at this point in the history
Magnetic properties
  • Loading branch information
JosePizarro3 committed Feb 7, 2024
2 parents 5651b50 + b7e8a3f commit 468acfb
Show file tree
Hide file tree
Showing 2 changed files with 237 additions and 0 deletions.
212 changes: 212 additions & 0 deletions runschema/calculation.py
Original file line number Diff line number Diff line change
Expand Up @@ -2029,6 +2029,206 @@ class RadiusOfGyration(AtomicGroup):
)


class MagneticShielding(MSection):
"""
Section containing the information of magnetic shielding tensors. This is the nuclear
response of a material to shield the effects of an applied external field. It is:
B_induced = - magnetic_shielding * B_external
The isotropic part can be calculated as 1 / 3 * Tr(magnetic_shielding).
See, e.g, https://pubs.acs.org/doi/10.1021/cr300108a.
"""

m_def = Section(validate=False)

value = Quantity(
type=np.float64,
shape=["n_atoms", 3, 3],
unit="dimensionless",
description="""
Value of the magnetic shielding tensor per atom. The first index runs for all the
atoms in the unit cell, while 3x3 refers to each axis direction. This quantity
relates with the induced magnetic field in the presence of an external magnetic as:
B_induced = - magnetic_shielding * B_external
""",
)

isotropic_value = Quantity(
type=np.float64,
shape=["n_atoms"],
unit="dimensionless",
description="""
Value of the isotropic part of the magnetic shielding tensor per atom. The first
index runs for all the atoms in the unit cell. This quantity relates with magnetic
shielding tensor as:
isotropic_value = 1 / 3 * Tr(value)
This part is relevant for solution state NMR or for powdered solids under magnetic
angle spinning conditions.
""",
)


class ElectricFieldGradient(MSection):
"""
Section containing the information of electric field gradient tensors. These tensors
are relevant for nuclear magnetic responses and address the interaction between the
quadrupole moment of the nucleus and the electric field gradient (EFG) at the nucleus
position generated by the surrounding charges.
The eigenvalues of these tensors can be used to compute the quadrupolar coupling constant
and the asymmetry parameter.
See, e.g, https://pubs.acs.org/doi/10.1021/cr300108a.
"""

# TODO generalize this to other cases

m_def = Section(validate=False)

contribution = Quantity(
type=MEnum("total", "local", "non_local"),
description="""
Type of contribution to the electric field gradient (EFG). The total EFG is
composed of `local` and `non_local` contributions.
""",
)

value = Quantity(
type=np.float64,
shape=["n_atoms", 3, 3],
unit="volt / meter ** 2",
description="""
Value of the electric field gradient (EFG) for each `contribution` per unit area.
The first index runs for all the atoms in the unit cell, while 3x3 refers to each
axis direction.
""",
)

quadrupolar_coupling_constant = Quantity(
type=np.float64,
shape=["n_atoms"],
description="""
Quadrupolar coupling constant for each atom in the unit cell. It is computed from
the eigenvalues of the EFG tensor as:
quadrupolar_coupling_constant = efg_zz * e * Z / h
where efg_zz is the largest eigenvalue of the EFG tensor, Z is the atomic number.
""",
)

asymmetry_parameter = Quantity(
type=np.float64,
shape=["n_atoms"],
description="""
Asymmetry parameter for each atom in the unit cell. It is computed from the
eigenvalues of the EFG tensor as:
asymmetry_parameter = (efg_xx - efg_yy) / efg_zz
where efg_xx, efg_yy and efg_zz are the eigenvalues of the EFG tensor ordered
such that |efg_zz| > |efg_yy| > |efg_xx|.
""",
)


class SpinSpinCoupling(MSection):
"""
Section containing the information of spin-spin couplings. These are the indirect
interactions between 2 nuclear spins that arises from hyperfine interactions between
the nuclei and local electrons.
Synonyms:
- IndirectSpinSpinCoupling
"""

# TODO extend this to other spin-spin coupling types besides indirect (which is useful in NMR)

m_def = Section(validate=False)

contribution = Quantity(
type=MEnum(
"total",
"direct_dipolar",
"fermi_contact",
"orbital_diamagnetic",
"orbital_paramagnetic",
"spin_dipolar",
),
description="""
Type of contribution to the indirect spin-spin coupling. The total indirect spin-spin
coupling is composed of:
`total` = `direct_dipolar` + J_coupling
Where the J_coupling is:
J_coupling = `fermi_contact`
+ `spin_dipolar`
+ `orbital_diamagnetic`
+ `orbital_paramagnetic`
See https://pubs.acs.org/doi/full/10.1021/cr300108a.
""",
)

value = Quantity(
type=np.float64,
shape=["n_atoms", "n_atoms", 3, 3],
unit="joule",
description="""
Value of the indirect spin-spin couplings for each contribution. The first and second
indices run for all the combinations of pairs of atoms in the unit cell, while
3x3 refers to each axis direction.
""",
)

reduced_value = Quantity(
type=np.float64,
shape=["n_atoms", "n_atoms", 3, 3],
unit="kelvin**2 / joule",
description="""
Reduced value of the indirect spin-spin couplings for each contribution. The first and second
indices run for all the combinations of pairs of atoms in the unit cell, while
3x3 refers to each axis direction. It relates with the normal value as:
reduced_value = value / (gyromagnetic_ratio_i * gyromagnetic_ratio_j * 2 * np.pi * hbar)
where i, j runs for each atom in the unit cell.
""",
)


class MagneticSusceptibility(MSection):
"""
Section containing the information of magnetic susceptibility tensor. Degree of
magnetization of a material in the presence of a magnetic field.
"""

# TODO currently only the macroscopic quantity is being supported

m_def = Section(validate=False)

scale_dimension = Quantity(
type=MEnum("microscopic", "macroscopic"),
description="""
Identifier of the scale dimension of the magnetic susceptibility tensor.
""",
)

value = Quantity( # TODO extend this to microscopic contributions
type=np.float64,
shape=[3, 3],
description="""
Value of the magnetic susceptibility. The 3x3 refers to each axis direction.
""",
)


class BaseCalculation(ArchiveSection):
"""
Contains computed properties of a configuration as defined by the corresponding
Expand Down Expand Up @@ -2190,6 +2390,18 @@ class BaseCalculation(ArchiveSection):

radius_of_gyration = SubSection(sub_section=RadiusOfGyration.m_def, repeats=True)

magnetic_shielding = SubSection(sub_section=MagneticShielding.m_def, repeats=True)

electric_field_gradient = SubSection(
sub_section=ElectricFieldGradient.m_def, repeats=True
)

spin_spin_coupling = SubSection(sub_section=SpinSpinCoupling.m_def, repeats=True)

magnetic_susceptibility = SubSection(
sub_section=MagneticSusceptibility.m_def, repeats=True
)

volume = Quantity(
type=np.dtype(np.float64),
shape=[],
Expand Down
25 changes: 25 additions & 0 deletions runschema/method.py
Original file line number Diff line number Diff line change
Expand Up @@ -2728,6 +2728,31 @@ class Method(ArchiveSection):

m_def = Section(validate=False)

label = Quantity(
type=MEnum("DFT", "TB", "GW", "DMFT", "BSE", "kMC", "NMR"),
description="""
Label to identify the method applied in the simulation. Allowed values are:
| Label | Name | Reference |
| ----- | ---- | ----------- |
| `'DFT'` | Density Functional Theory | https://en.wikipedia.org/wiki/Density_functional_theory |
| `'TB'` | Tight-Binding models | https://en.wikipedia.org/wiki/Tight_binding |
| `'GW'` | GW approximation | https://en.wikipedia.org/wiki/GW_approximation |
| `'DMFT'` | Dynamical Mean-Field Theory | https://en.wikipedia.org/wiki/GW_approximation |
| `'BSE'` | Bethe-Salpeter Equation | https://en.wikipedia.org/wiki/Bethe-Salpeter_equation |
| `'kMC'` | Kinetic Monte Carlo |https://en.wikipedia.org/wiki/Kinetic_Monte_Carlo |
| `'NMR'` | Nuclear Magnetic Resonance | https://en.wikipedia.org/wiki/Nuclear_magnetic_resonance |
""",
)

stress_tensor_method = Quantity(
type=str,
shape=[],
Expand Down

0 comments on commit 468acfb

Please sign in to comment.