Skip to content

Commit ce27760

Browse files
committed
add two method of orb_mag
1 parent 9677d70 commit ce27760

13 files changed

Lines changed: 1807 additions & 0 deletions

File tree

source/source_esolver/esolver_ks_lcao.cpp

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "source_lcao/rho_tau_lcao.h" // mohan add 20251024
2222
#include "source_lcao/LCAO_set.h" // mohan add 20251111
2323
#include "source_lcao/module_orbital_mag/orbital_mag.h"
24+
#include "source_lcao/module_orbital_mag/orbital_mag_dm.h"
2425

2526
namespace ModuleESolver
2627
{
@@ -582,6 +583,35 @@ void ESolver_KS_LCAO<TK, TR>::after_scf(UnitCell& ucell, const int istep, const
582583
GlobalV::ofs_running << " M_y = " << M_orb.y << std::endl;
583584
GlobalV::ofs_running << " M_z = " << M_orb.z << std::endl;
584585
}
586+
587+
//! 5) Calculate orbital magnetic moment using density matrix method if requested
588+
if (PARAM.inp.out_orbital_mag_dm)
589+
{
590+
hamilt::OrbitalMagDM<TK> orbital_mag_dm(ucell,
591+
this->kv,
592+
*this->dmat.dm,
593+
hamilt_lcao->getHR(),
594+
hamilt_lcao->getSR(),
595+
&this->pv,
596+
this->orb_);
597+
ModuleBase::Vector3<double> M_itin = orbital_mag_dm.calculate_orbital_moment();
598+
ModuleBase::Vector3<double> M_local = orbital_mag_dm.calculate_local_moment();
599+
ModuleBase::Vector3<double> M_total = M_itin + M_local;
600+
601+
GlobalV::ofs_running << "\n ORBITAL MAGNETIC MOMENT (DM method, Bohr magneton):" << std::endl;
602+
GlobalV::ofs_running << " --- Itinerant contribution ---" << std::endl;
603+
GlobalV::ofs_running << " M_x = " << M_itin.x << std::endl;
604+
GlobalV::ofs_running << " M_y = " << M_itin.y << std::endl;
605+
GlobalV::ofs_running << " M_z = " << M_itin.z << std::endl;
606+
GlobalV::ofs_running << " --- Local (on-site) contribution ---" << std::endl;
607+
GlobalV::ofs_running << " M_x = " << M_local.x << std::endl;
608+
GlobalV::ofs_running << " M_y = " << M_local.y << std::endl;
609+
GlobalV::ofs_running << " M_z = " << M_local.z << std::endl;
610+
GlobalV::ofs_running << " --- Total orbital moment ---" << std::endl;
611+
GlobalV::ofs_running << " M_x = " << M_total.x << std::endl;
612+
GlobalV::ofs_running << " M_y = " << M_total.y << std::endl;
613+
GlobalV::ofs_running << " M_z = " << M_total.z << std::endl;
614+
}
585615
}
586616

587617
ModuleBase::timer::tick("ESolver_KS_LCAO", "after_scf");

source/source_io/cal_r_overlap_R.cpp

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,55 @@ ModuleBase::Vector3<double> cal_r_overlap_R::get_psi_r_psi(const ModuleBase::Vec
516516
return temp_prp;
517517
}
518518

519+
ModuleBase::Vector3<std::complex<double>> cal_r_overlap_R::get_psi_L_psi(
520+
const ModuleBase::Vector3<double>& R1,
521+
const int& T1,
522+
const int& L1,
523+
const int& m1,
524+
const int& N1,
525+
const ModuleBase::Vector3<double>& R2,
526+
const int& T2,
527+
const int& L2,
528+
const int& m2,
529+
const int& N2)
530+
{
531+
ModuleBase::Vector3<double> origin_point(0.0, 0.0, 0.0);
532+
double factor = sqrt(ModuleBase::FOUR_PI / 3.0);
533+
const ModuleBase::Vector3<double>& distance = R2 - R1;
534+
535+
// grad_r_beta[beta] = ∂/∂R · ⟨φ_μ|(r-R_B)_beta|φ_ν⟩ (a Vector3<double> for each beta)
536+
// Following the same sign convention as get_psi_r_psi:
537+
// mA2=0 → z component (positive factor)
538+
// mA2=1 → x component (negative factor)
539+
// mA2=2 → y component (negative factor)
540+
541+
// grad of ⟨φ|(r-R_B)_x|φ⟩ w.r.t. R
542+
ModuleBase::Vector3<double> grad_rx
543+
= -1.0 * factor
544+
* center2_orb21_r[T1][T2][L1][N1][L2].at(N2).cal_grad_overlap(origin_point, distance, m1, 1, m2);
545+
546+
// grad of ⟨φ|(r-R_B)_y|φ⟩ w.r.t. R
547+
ModuleBase::Vector3<double> grad_ry
548+
= -1.0 * factor
549+
* center2_orb21_r[T1][T2][L1][N1][L2].at(N2).cal_grad_overlap(origin_point, distance, m1, 2, m2);
550+
551+
// grad of ⟨φ|(r-R_B)_z|φ⟩ w.r.t. R
552+
ModuleBase::Vector3<double> grad_rz
553+
= factor
554+
* center2_orb21_r[T1][T2][L1][N1][L2].at(N2).cal_grad_overlap(origin_point, distance, m1, 0, m2);
555+
556+
// L_x = i * [∂/∂R_y ⟨r_z⟩ - ∂/∂R_z ⟨r_y⟩]
557+
// L_y = i * [∂/∂R_z ⟨r_x⟩ - ∂/∂R_x ⟨r_z⟩]
558+
// L_z = i * [∂/∂R_x ⟨r_y⟩ - ∂/∂R_y ⟨r_x⟩]
559+
const std::complex<double> imag_i(0.0, 1.0);
560+
561+
std::complex<double> Lx = imag_i * (grad_rz.y - grad_ry.z);
562+
std::complex<double> Ly = imag_i * (grad_rx.z - grad_rz.x);
563+
std::complex<double> Lz = imag_i * (grad_ry.x - grad_rx.y);
564+
565+
return ModuleBase::Vector3<std::complex<double>>(Lx, Ly, Lz);
566+
}
567+
519568
void cal_r_overlap_R::get_psi_r_beta(const UnitCell& ucell,
520569
std::vector<std::vector<double>>& nlm,
521570
const ModuleBase::Vector3<double>& R1,

source/source_io/cal_r_overlap_R.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
#include "source_base/sph_bessel_recursive.h"
66
#include "source_base/vector3.h"
77
#include "source_base/ylm.h"
8+
#include <complex>
89
#include "source_basis/module_ao/ORB_atomic_lm.h"
910
#include "source_basis/module_ao/ORB_gaunt_table.h"
1011
#include "source_basis/module_ao/ORB_read.h"
@@ -46,6 +47,18 @@ class cal_r_overlap_R
4647
const int& m2,
4748
const int& N2
4849
);
50+
ModuleBase::Vector3<std::complex<double>> get_psi_L_psi(
51+
const ModuleBase::Vector3<double>& R1,
52+
const int& T1,
53+
const int& L1,
54+
const int& m1,
55+
const int& N1,
56+
const ModuleBase::Vector3<double>& R2,
57+
const int& T2,
58+
const int& L2,
59+
const int& m2,
60+
const int& N2
61+
);
4962
void get_psi_r_beta(
5063
const UnitCell& ucell,
5164
std::vector<std::vector<double>>& nlm,

source/source_io/module_parameter/input_parameter.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,7 @@ struct Input_para
402402
bool out_mat_r = false; ///< jingan add 2019-8-14, output r(R) matrix.
403403
int out_wfc_lcao = 0; ///< output the wave functions in local basis.
404404
bool out_orbital_mag = false; ///< output orbital magnetic moment (LCAO multi-k only)
405+
bool out_orbital_mag_dm = false; ///< output orbital magnetic moment using density matrix method
405406
bool out_dipole = false; ///< output the dipole or not
406407
bool out_efield = false; ///< output the efield or not
407408
int out_current = 0; ///< output the current or not

source/source_io/module_parameter/read_input_item_output.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,18 @@ void ReadInput::item_output()
163163
};
164164
this->add_item(item);
165165
}
166+
{
167+
Input_Item item("out_orbital_mag_dm");
168+
item.annotation = "output orbital magnetic moment using density matrix method (LCAO multi-k only)";
169+
read_sync_bool(input.out_orbital_mag_dm);
170+
item.check_value = [](const Input_Item& item, const Parameter& para) {
171+
if (para.input.basis_type != "lcao" && para.input.out_orbital_mag_dm)
172+
{
173+
ModuleBase::WARNING_QUIT("ReadInput", "out_orbital_mag_dm is only for lcao");
174+
}
175+
};
176+
this->add_item(item);
177+
}
166178
{
167179
Input_Item item("out_proj_band");
168180
item.annotation = "output projected band structure";

source/source_io/test/CMakeLists.txt

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -279,6 +279,25 @@ AddTest(
279279
)
280280
endif()
281281

282+
if(ENABLE_LCAO)
283+
AddTest(
284+
TARGET MODULE_IO_cal_r_overlap_R_L_test
285+
LIBS parameter base ${math_libs} device numerical_atomic_orbitals container orb
286+
SOURCES
287+
cal_r_overlap_R_L_test.cpp
288+
../cal_r_overlap_R.cpp
289+
../single_R_io.cpp
290+
../../source_cell/atom_spec.cpp
291+
../../source_cell/parallel_kpoints.cpp
292+
../../source_cell/test/support/mock_unitcell.cpp
293+
../../source_lcao/center2_orb.cpp
294+
../../source_lcao/center2_orb-orb11.cpp
295+
../../source_lcao/center2_orb-orb21.cpp
296+
../../source_lcao/center2_orb-orb22.cpp
297+
../orb_io.cpp
298+
)
299+
endif()
300+
282301
AddTest(
283302
TARGET MODULE_IO_write_elf_logic_test
284303
SOURCES write_elf_logic_test.cpp

0 commit comments

Comments
 (0)