QE_utils¶
-
libra_py.QE_utils.
get_value
(params, key, default, typ)[source]¶ Function to extract parameter from the dictionary
- Parameters
params (dict) – A dictionary containing important simulation parameters
key (string) – The name of the variable that we wish to extract from the params dictionary
default (various types) – The default value assigned to a dictionary key
typ (string) – The data type assigned to a value that is extracted from the dictionary
- Returns
a value from the params dictionary that is of type typ
- Return type
various types
-
libra_py.QE_utils.
merge_orbitals
(Ca, Cb)[source]¶ This function puts two matrices together into a single matrix
param[in] Ca Coefficient matrix corresponding to alpha orbitals of size N_pw x N_Mo param[in] Cb Coefficient matrix corresponding to beta orbitals of size N_pw x N_Mo
Returns: A single matrix of size N_pw x 2*N_Mo
-
libra_py.QE_utils.
orthogonalize_orbitals
(C)[source]¶ This function takes an input of orbitals (C), which may not be rigorously orthogonal, finds a suitable transformation (U) and converts them into rigorously orthogonal orbitals (C_tilda)
C_tilda = C * U, so if you want
C_tilda^+ * C_tilda = I, you’ll find that
U = S^{-1/2}, where S = C^+ * C
- Parameters
C (CMATRIX(N_pw, N_mo)) – just alpha or beta orbitals
- Returns
- just alpha or beta orbitals, where
the overlap matrix constructed using this matrix is the identity matrix
- Return type
CMATRIX(N_pw, N_mo)
-
libra_py.QE_utils.
orthogonalize_orbitals2
(Ca, Cb)[source]¶ Ca and Cb = N_pw x N_mo - represent the spin-components of the adiabatic states
This function takes an input of orbitals (C), which may not be rigorously orthogonal, finds a suitable transformation (U) and converts them into rigorously orthogonal orbitals (C_tilda)
For each channel:
C_tilda = C * U, so if you want
C_tilda^+ * C_tilda = I, you’ll find that
U = S^{-1/2}, where $S = Ca^+ * Ca + Cb^+ * Cb$
- Parameters
Ca (CMATRIX(N_pw, N_mo)) – alpha-component of the adiabatic states
Cb (CMATRIX(N_pw, N_mo)) – beta-component of the adiabatic states
- Returns
- Two matricies where the overlap matrix
constructed using this matrix is the identity matrix
- Return type
( CMATRIX(N_pw, N_mo) , CMATRIX(N_pw, N_mo) )
-
libra_py.QE_utils.
post_process
(coeff, ene, issoc)[source]¶ Post-processing of the data extracted from QE output files
- Parameters
coeff (list of CMATRIX) – PW coefficients for orbitals, potentially spin-resolved
ene (list of CMATRIX) – energies of KS orbitals, potentially spin-resolved
issoc (int) –
flag to indicate whether the orbitals are 2-component spinors (with SOC) or regular KS orbitals, one per spin channel
0 : no SOC
1 : yes SOC
Returns:
(list[0], list[1]), where :
No-SOC case: list[0] = list[1] SOC case: 2 lists, where list[0] = alpha components, list[1] = beta components
Notes
In SOC case (spinor):
- coeff[0] - a N_pw x 2*N matrix of type: (psi_0^alp, psi_0^bet, … psi_{N-1}^alp, psi_{N-1}^bet)
where each psi is a colum of the PW coefficients for given KS orbital (spatial component for each spin)
- ene[0] - a 2*N x 2*N matrix of energies coming in pairs: e_{2*i} = e_{2*i+1}, because these are the
energies of the same orbital, just its different spin components
We then split the coeff[0] matrix into a pair of N_pw x N matrices that represent alpha and beta spatial components of the wavefunction, separately
However, the number of <b>spin<>-orbitals will be twice that of the N, so we need to construct new matrices with spin-orbitals.
So that we have both psi_i = (psi_i_alp, psi_i_bet) and psi_{i+N} = (psi_i_bet, psi_i_alp) pairs of spin-orbitals (this is needed to represent the indistinguishable nature of electrons) i = 0,…N-1, where N - is the number of pairs of read spinors = N_adi_ks_orb
In non-SOC case (spin-polarized):
We directly get a pair of N_pw x N_mo_dia matrices that represent alpha and beta spatial components of the wavefunction
coeff[0] - a N_pw x N matrix of type: (psi_0^alp, … psi_{N-1}^alp) coeff[1] - a N_pw x N matrix of type: (psi_0^bet, … psi_{N-1}^bet)
where each psi is a colum of the PW coefficients for given KS orbital (spatial component for each spin)
ene[0] - a N x N matrix of alpha KS orbital energies ene[1] - a N x N matrix of beta KS orbital energies
Eventually:
“alpha-block” “beta-block”
C_adi[0] = (psi_0^alp,… psi_{N-1}^alp, psi_N^alp, … psi_{2N-1}^alp) alpha-components of spinors C_adi[1] = (psi_0^bet,… psi_{N-1}^bet, psi_N^bet, … psi_{2N-1}^bet) beta-components of spinors
same energies in SOC case or non-polarized non-SOC different energies in spin-polarized non-SOC
Also: psi_0^alp = psi_N^bet and psi_0^bet = psi_N^alp, and so on
E^alpha-block 0 |E_adi = | | | 0 E^beta-block |
E^alpha-block = E^beta-block (SOC or non-polarized non-SOC) E^alpha-block != E^beta-block (spin-polarized non-SOC)
-
libra_py.QE_utils.
split_orbitals_energies
(C, E)[source]¶ - In SOC, non-collinear case, the orbitals are 2-component spinors:
- psi_i^alp | | E_i_alp |
- psi_i = | |, so E = | |
- psi_i^bet | | E_i_bet |
So, the wfc we read from the QE calculations, in this case is composed of such pairs, going in this order, so:
psi_i^alp, psi_i^bet, psi_{i+1}^alp, psi_{i+1}^bet, …
Thus, there are 2*N_mo_adi columns, so we need to extract spin-components into 2 matrices
param[in] C Coefficient matrix of size N_pw x 2*N_Mo param[in] E Eigenvalue matrix of size 2*N_mo x 2*N_Mo
Returns: Matricies for the alpha and beta components of the input matricies