How to determine whether spin polarization is turned on for dos calculation of a material?

Dear Materials Project Team,
Greetings!
I want to query some questions about dos:

1、As shown in the following code, does the presence of “orb_dos.densities[Spin.down]” mean that Spin polarization is turned on? If “orb_dos.densities[Spin.down]” is None, does Spin polarization not turn on?
2、If Spin polarization is not turned on, the total dos of an orbit is “orb_dos.densities[spin.up]”, right?
3、If spin polarization is turned on, if I want to get the total dos of an orbital, I need to add the absolute value of orb_dos.densities[spin.up] to the absolute value of orb_dos.densities[spin.down], right?
For example, for the d orbital, it’s absolute value of d_spin_up plus absolute value of d_spin_down, right?
4、Is there a more convenient way to get the total dos of s,p,d and f orbitals?

from pymatgen.electronic_structure.core import Spin
from mp_api.client import MPRester
import matplotlib.pyplot as plt

with MPRester("XXX") as mpr:
    dos = mpr.get_dos_by_material_id("mp-XXX")

energies = dos.energies  
fermi_level = dos.efermi
total_dos_up = dos.densities[Spin.up]  
total_dos_down = dos.densities.get(Spin.down, None)  
energies_fermi = energies - fermi_level

spd_dos = dos.get_spd_dos()

s_spin_up = None  
s_spin_down = None  
p_spin_up = None  
p_spin_down = None  
d_spin_up = None 
d_spin_down = None  
f_spin_up = None  
f_spin_down = None  

for orb, orb_dos in spd_dos.items():

    if orb.name == 's' and Spin.up in orb_dos.densities:
        s_spin_up = orb_dos.densities[Spin.up]
    if orb.name == 's' and Spin.down in orb_dos.densities:
        s_spin_down = orb_dos.densities[Spin.down]                    
    if orb.name == 'p' and Spin.up in orb_dos.densities:
        p_spin_up = orb_dos.densities[Spin.up]
    if orb.name == 'p' and Spin.down in orb_dos.densities:
        p_spin_down = orb_dos.densities[Spin.down]                      
    if orb.name == 'd' and Spin.up in orb_dos.densities:
        d_spin_up = orb_dos.densities[Spin.up]
    if orb.name == 'd' and Spin.down in orb_dos.densities:
        d_spin_down = orb_dos.densities[Spin.down]  
    if orb.name == 'f' and Spin.up in orb_dos.densities:
        f_spin_up = orb_dos.densities[Spin.up]
    if orb.name == 'f' and Spin.down in orb_dos.densities:
        f_spin_down = orb_dos.densities[Spin.down]          

Looking forward to your reply, thank you very much.

Hey @WoGaho:

  1. Yes the presence of a spin-down component indicates that a spin-polarized calculation was performed

  2. Without spin polarization, the spin-up component is (counter intuitively) the total DOS. To check this, you can roughly estimate the number of electrons in occupied states as:

import numpy as np

nelect_sr = {spin: np.sum(sr_dos[dos.energies <= dos.efermi]) * (dos.energies[1] - dos.energies[0]) for spin, sr_dos in dos.densities.items()}

(Just the rectangle rule for integrating the DOS up the Fermi level.)
The caveat is that you should take into account the number of valence electrons from the pseudopotential only.

  1. The DOS is non-negative, so you can just sum the spin-up and spin-down component of the DOS for a given orbital-resolved character, or the total DOS.

  2. Why not this:

spd_dos = {orb_char.name : np.sum([*orb_res_dos.densities.values()],axis=0) for orb_char, orb_res_dos in dos.get_spd_dos().items()}
1 Like

@Aaron_Kaplan Thank you for your answer, your answer is very professional, let me deeply inspired!