|
2 | 2 | #include "source_hamilt/module_xc/xc_functional.h" |
3 | 3 | #include "source_io/module_parameter/parameter.h" |
4 | 4 | #include "surchem.h" |
5 | | -#include <cmath> |
6 | 5 | #include <vector> |
7 | 6 | #include <algorithm> |
8 | 7 | #include <iostream> |
@@ -45,10 +44,9 @@ void surchem::cal_smpbe_physics(const int nrxx, |
45 | 44 | double u = z * beta * phi_R[ir]; |
46 | 45 |
|
47 | 46 | // 限制 u 的范围防止溢出 (Though ABACUS uses double, safety first) |
48 | | - if(u > 20.0) u = 20.0; |
49 | | - if(u < -20.0) u = -20.0; |
| 47 | + u = std::max(-20.0, std::min(u, 20.0)); |
50 | 48 |
|
51 | | - double exp_u = std::exp(u); |
| 49 | + double exp_u = exp(u); |
52 | 50 | double exp_neg_u = 1.0 / exp_u; |
53 | 51 | double sinh_u = 0.5 * (exp_u - exp_neg_u); |
54 | 52 | double cosh_u = 0.5 * (exp_u + exp_neg_u); |
@@ -108,7 +106,12 @@ void cal_dielectric_saturation(const int nrxx, |
108 | 106 | if(x < 1e-4) { |
109 | 107 | langevin = x / 3.0; |
110 | 108 | } else { |
111 | | - langevin = (1.0 / tanh(x)) - (1.0 / x); |
| 109 | + // 优化尝试:利用 libm::exp 替换 tanh |
| 110 | + // tanh(x) = 1 - 2 / (exp(2x) + 1) |
| 111 | + double exp_2x = exp(2.0 * x); |
| 112 | + double tanh_x = 1.0 - 2.0 / (exp_2x + 1.0); |
| 113 | + |
| 114 | + langevin = (1.0 / tanh_x) - (1.0 / x); |
112 | 115 | } |
113 | 116 |
|
114 | 117 | double term_dipole = 0.0; |
@@ -140,6 +143,7 @@ void shape_gradn(const double* PS_TOTN_real, const ModulePW::PW_Basis* rho_basis |
140 | 143 | // Gaussian error function derivative chain rule |
141 | 144 | epr_z = log(std::max(PS_TOTN_real[ir], min) / PARAM.inp.nc_k) / sqrt(2) / PARAM.inp.sigma_k; |
142 | 145 | eprime[ir] = epr_c * exp(-pow(epr_z, 2)) / std::max(PS_TOTN_real[ir], min); |
| 146 | + |
143 | 147 | } |
144 | 148 | } |
145 | 149 |
|
|
0 commit comments