From b7e8a3f07586dde6ceb3bf7083209d5e8169dc41 Mon Sep 17 00:00:00 2001 From: JosePizarro3 Date: Fri, 2 Feb 2024 11:29:32 +0100 Subject: [PATCH] Added magnetic properties and Method.label --- runschema/calculation.py | 212 +++++++++++++++++++++++++++++++++++++++ runschema/method.py | 25 +++++ 2 files changed, 237 insertions(+) diff --git a/runschema/calculation.py b/runschema/calculation.py index 0bd2ad0..a30e7d1 100644 --- a/runschema/calculation.py +++ b/runschema/calculation.py @@ -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 @@ -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=[], diff --git a/runschema/method.py b/runschema/method.py index 10eb1d3..8e0e941 100644 --- a/runschema/method.py +++ b/runschema/method.py @@ -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=[],