|
18 | 18 | * |
19 | 19 | * FIXME: the following part will be transfered to TwoCenterIntegrator soon |
20 | 20 | * |
| 21 | + * Notation |
| 22 | + * -------- |
| 23 | + * ylm: complex spherical harmonics |
| 24 | + * slm: solid (real) spherical harmonics |
| 25 | + * |
| 26 | + * Changelog |
| 27 | + * --------- |
| 28 | + * Switch to support the solid spherical harmonics to keep consistent with |
| 29 | + * implementations of other parts. |
| 30 | + * Formulation (in Chinese): |
| 31 | + * https://my.feishu.cn/wiki/D0enwcUKfiJgtSkJ5scc9Dagntc |
21 | 32 | */ |
22 | 33 |
|
23 | | -// L+|l, m> = sqrt((l-m)(l+m+1))|l, m+1>, return the sqrt((l-m)(l+m+1)) |
24 | | -double _lplus_on_ylm(const int l, const int m) |
| 34 | +// L+ylm = sqrt((l-m)(l+m+1))ylm+1, return the sqrt((l-m)(l+m+1)) |
| 35 | +double _lambda_plus(const int l, const int m) |
25 | 36 | { |
26 | | - return std::sqrt((l - m) * (l + m + 1)); |
| 37 | + return std::sqrt((l - m) * (l + m + 1)); // NOTE: complex spherical harmonics |
27 | 38 | } |
28 | 39 |
|
29 | | -// L-|l, m> = sqrt((l+m)(l-m+1))|l, m-1>, return the sqrt((l+m)(l-m+1)) |
30 | | -double _lminus_on_ylm(const int l, const int m) |
| 40 | +// L-ylm = sqrt((l+m)(l-m+1))ylm-1, return the sqrt((l+m)(l-m+1)) |
| 41 | +double _lambda_minus(const int l, const int m) |
31 | 42 | { |
32 | | - return std::sqrt((l + m) * (l - m + 1)); |
| 43 | + return std::sqrt((l + m) * (l - m + 1)); // NOTE: complex spherical harmonics |
33 | 44 | } |
34 | 45 |
|
| 46 | +const std::complex<double> i = {0., 1.}; |
| 47 | +const double invsqrt2 = std::sqrt(2) * 0.5; |
| 48 | + |
35 | 49 | std::complex<double> ModuleIO::cal_LzijR( |
36 | 50 | const std::unique_ptr<TwoCenterIntegrator>& calculator, |
37 | 51 | const int it, const int ia, const int il, const int iz, const int mi, |
38 | 52 | const int jt, const int ja, const int jl, const int jz, const int mj, |
39 | 53 | const ModuleBase::Vector3<double>& vR) |
40 | 54 | { |
| 55 | + if(mj == 0) { |
| 56 | + return std::complex<double>(0.); |
| 57 | + } |
41 | 58 | double val_ = 0; |
42 | | - calculator->calculate(it, il, iz, mi, jt, jl, jz, mj, vR, &val_); |
43 | | - return std::complex<double>(mi) * val_; |
| 59 | + calculator->calculate(it, il, iz, mi, jt, jl, jz, -mj, vR, &val_); |
| 60 | + return i * static_cast<double>(mj) * val_; |
44 | 61 | } |
45 | 62 |
|
46 | | -std::complex<double> ModuleIO::cal_LyijR( |
| 63 | +std::complex<double> ModuleIO::cal_LxijR( |
47 | 64 | const std::unique_ptr<TwoCenterIntegrator>& calculator, |
48 | 65 | const int it, const int ia, const int il, const int iz, const int im, |
49 | 66 | const int jt, const int ja, const int jl, const int jz, const int jm, |
50 | 67 | const ModuleBase::Vector3<double>& vR) |
51 | 68 | { |
52 | | - // Ly = -i/2 * (L+ - L-) |
53 | | - const double plus_ = _lplus_on_ylm(jl, jm); |
54 | | - const double minus_ = _lminus_on_ylm(jl, jm); |
55 | | - double val_plus = 0, val_minus = 0; |
56 | | - if (plus_ != 0) |
57 | | - { |
58 | | - calculator->calculate(it, il, iz, im, jt, jl, jz, jm + 1, vR, &val_plus); |
59 | | - val_plus *= plus_; |
| 69 | + const double lmbdp = _lambda_plus(jl, jm); |
| 70 | + const double lmbdm = _lambda_minus(jl, jm); |
| 71 | + // two-center-integral placeholders |
| 72 | + double valp = 0.; |
| 73 | + double valm = 0.; |
| 74 | + if (jm > 1) { |
| 75 | + if (std::fabs(lmbdp) > 1e-12) { |
| 76 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -(jm+1), vR, &valp); |
| 77 | + } |
| 78 | + if (std::fabs(lmbdm) > 1e-12) { |
| 79 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -(jm-1), vR, &valm); |
| 80 | + } |
| 81 | + return i * 0.5 * (lmbdp * valp + lmbdm * valm); |
60 | 82 | } |
61 | | - if (minus_ != 0) |
62 | | - { |
63 | | - calculator->calculate(it, il, iz, im, jt, jl, jz, jm - 1, vR, &val_minus); |
64 | | - val_minus *= minus_; |
| 83 | + if (jm == 1) { |
| 84 | + if (std::fabs(lmbdp) > 1e-12) { |
| 85 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -2, vR, &valp); |
| 86 | + } |
| 87 | + return i * 0.5 * lmbdp * valp; |
| 88 | + } |
| 89 | + if (jm == 0) { |
| 90 | + const double lmbd = _lambda_plus(jl, 0); // std::sqrt(jl*(jl+1)) |
| 91 | + if (std::fabs(lmbd) > 1e-12) { |
| 92 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -1, vR, &valp); |
| 93 | + } |
| 94 | + return i * invsqrt2 * lmbd * valp; |
| 95 | + } |
| 96 | + if (jm == -1) { |
| 97 | + if (std::fabs(lmbdp) > 1e-12) { |
| 98 | + calculator->calculate(it, il, iz, im, jt, jl, jz, 0, vR, &valp); |
| 99 | + } |
| 100 | + if (std::fabs(lmbdm) > 1e-12) { |
| 101 | + calculator->calculate(it, il, iz, im, jt, jl, jz, 2, vR, &valm); |
| 102 | + } |
| 103 | + return -i * 0.5 * (std::sqrt(2) * lmbdp * valp + lmbdm * valm); |
65 | 104 | } |
66 | | - return std::complex<double>(0, -0.5) * (val_plus - val_minus); |
| 105 | + if (jm < -1) { |
| 106 | + if (std::fabs(lmbdp) > 1e-12) { |
| 107 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -(jm+1), vR, &valp); |
| 108 | + } |
| 109 | + if (std::fabs(lmbdm) > 1e-12) { |
| 110 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -(jm-1), vR, &valm); |
| 111 | + } |
| 112 | + return -i * 0.5 * (lmbdp * valp + lmbdm * valm); |
| 113 | + } |
| 114 | + assert(false); // inaccessible |
67 | 115 | } |
68 | 116 |
|
69 | | -std::complex<double> ModuleIO::cal_LxijR( |
| 117 | +std::complex<double> ModuleIO::cal_LyijR( |
70 | 118 | const std::unique_ptr<TwoCenterIntegrator>& calculator, |
71 | 119 | const int it, const int ia, const int il, const int iz, const int im, |
72 | 120 | const int jt, const int ja, const int jl, const int jz, const int jm, |
73 | 121 | const ModuleBase::Vector3<double>& vR) |
74 | 122 | { |
75 | | - // Lx = 1/2 * (L+ + L-) |
76 | | - const double plus_ = _lplus_on_ylm(jl, jm); |
77 | | - const double minus_ = _lminus_on_ylm(jl, jm); |
78 | | - double val_plus = 0, val_minus = 0; |
79 | | - if (plus_ != 0) |
80 | | - { |
81 | | - calculator->calculate(it, il, iz, im, jt, jl, jz, jm + 1, vR, &val_plus); |
82 | | - val_plus *= plus_; |
| 123 | + const double lmbdp = _lambda_plus(jl, jm); |
| 124 | + const double lmbdm = _lambda_minus(jl, jm); |
| 125 | + // two-center-integral placeholders |
| 126 | + double valp = 0.; |
| 127 | + double valm = 0.; |
| 128 | + if (jm > 1) { |
| 129 | + if (std::fabs(lmbdp) > 1e-12) { |
| 130 | + calculator->calculate(it, il, iz, im, jt, jl, jz, jm+1, vR, &valp); |
| 131 | + } |
| 132 | + if (std::fabs(lmbdm) > 1e-12) { |
| 133 | + calculator->calculate(it, il, iz, im, jt, jl, jz, jm-1, vR, &valm); |
| 134 | + } |
| 135 | + return -i * 0.5 * (lmbdp * valp - lmbdm * valm); |
83 | 136 | } |
84 | | - if (minus_ != 0) |
85 | | - { |
86 | | - calculator->calculate(it, il, iz, im, jt, jl, jz, jm - 1, vR, &val_minus); |
87 | | - val_minus *= minus_; |
| 137 | + if (jm == 1) { |
| 138 | + if (std::fabs(lmbdp) > 1e-12) { |
| 139 | + calculator->calculate(it, il, iz, im, jt, jl, jz, 2, vR, &valp); |
| 140 | + } |
| 141 | + if (std::fabs(lmbdm) > 1e-12) { |
| 142 | + calculator->calculate(it, il, iz, im, jt, jl, jz, 0, vR, &valm); |
| 143 | + } |
| 144 | + return -i * 0.5 * (lmbdp * valp - std::sqrt(2) * lmbdm * valm); |
| 145 | + } |
| 146 | + if (jm == 0) { |
| 147 | + const double lmbd = _lambda_plus(jl, 0); // std::sqrt(l*(l+1)) |
| 148 | + if (std::fabs(lmbd) > 1e-12) { |
| 149 | + calculator->calculate(it, il, iz, im, jt, jl, jz, 1, vR, &valp); |
| 150 | + } |
| 151 | + return -i * invsqrt2 * lmbd * valp; |
| 152 | + } |
| 153 | + if (jm == -1) { |
| 154 | + if (std::fabs(lmbdm) > 1e-12) { |
| 155 | + calculator->calculate(it, il, iz, im, jt, jl, jz, -2, vR, &valm); |
| 156 | + } |
| 157 | + return -i * 0.5 * lmbdm * valm; |
| 158 | + } |
| 159 | + if (jm < -1) { |
| 160 | + if (std::fabs(lmbdp) > 1e-12) { |
| 161 | + calculator->calculate(it, il, iz, im, jt, jl, jz, jm+1, vR, &valp); |
| 162 | + } |
| 163 | + if (std::fabs(lmbdm) > 1e-12) { |
| 164 | + calculator->calculate(it, il, iz, im, jt, jl, jz, jm-1, vR, &valm); |
| 165 | + } |
| 166 | + return i * 0.5 * (lmbdp * valp - lmbdm * valm); |
88 | 167 | } |
89 | | - return std::complex<double>(0.5) * (val_plus + val_minus); |
| 168 | + assert(false); // inaccessible |
90 | 169 | } |
91 | 170 |
|
92 | 171 | ModuleIO::AngularMomentumCalculator::AngularMomentumCalculator( |
|
0 commit comments