1+ #include " mt_poisson.h"
2+ #include " module_base/constants.h" // 获取 PI, FOUR_PI
3+ #include < iostream>
4+
5+ // 如果需要报错功能
6+ #include " module_base/global_function.h"
7+
8+ double MTPoisson::get_screen_val_g0 (double L, std::string type) {
9+ // 对应 CP2K 逻辑: IF (grid%have_g0) screen_function%array(1) = pi*zlength*zlength/2.0_dp
10+ if (type == " 2D" ) {
11+ return ModuleBase::PI * L * L / 2.0 ;
12+ }
13+ // 0D 暂时略过,因为需要实空间积分或者 alpha 处理
14+ return 0.0 ;
15+ }
16+
17+ double MTPoisson::get_screen_val (double g2,
18+ const ModuleBase::Vector3<double >& g_vec,
19+ double L,
20+ double alpha,
21+ std::string type,
22+ int direction)
23+ {
24+ // 安全检查:G^2 非常小视为 G=0,返回0 (外部应该处理了 G=0 的情况)
25+ if (g2 < 1e-10 ) return 0.0 ;
26+
27+ if (type == " 2D" ) {
28+ // 1. 确定非周期方向的分量 (G_special)
29+ double g_special = 0.0 ;
30+ switch (direction) {
31+ case 0 : g_special = g_vec.x ; break ; // X 方向真空
32+ case 1 : g_special = g_vec.y ; break ; // Y 方向真空 (默认)
33+ case 2 : g_special = g_vec.z ; break ; // Z 方向真空
34+ default :
35+ // 默认回落到 Y
36+ g_special = g_vec.y ;
37+ break ;
38+ }
39+
40+ // 2. 调用核心公式
41+ return calculate_mt2d (g2, g_special, L);
42+ }
43+ else if (type == " 0D" ) {
44+ // 0D 逻辑 (尚未完全移植,需要 erfc 等特殊处理)
45+ return 0.0 ;
46+ }
47+
48+ return 0.0 ;
49+ }
50+
51+ double MTPoisson::calculate_mt2d (double g2, double g_special, double L) {
52+ // 公式来源: CP2K mt_util.F (Martyna-Tuckerman, 1999)
53+ // V_screen(G) = - (4pi/G^2) * cos(G_z * L / 2) * exp(-G_xy * L / 2)
54+ // 这里 G_z 泛指非周期方向分量(g_special),G_xy 泛指周期平面分量
55+
56+ // 1. 计算标准库仑项 (注意符号,这里只计算系数)
57+ // 最终公式是: fac = (4pi/G^2) + V_screen
58+ // 所以 V_screen = (4pi/G^2) * [ -cos(...) * exp(...) ]
59+ double coulomb_term = ModuleBase::FOUR_PI / g2;
60+
61+ // 2. 计算周期性平面内的 G 分量模长
62+ // G^2 = G_special^2 + G_planar^2 => G_planar = sqrt(G^2 - G_special^2)
63+ double g_planar = std::sqrt (std::abs (g2 - g_special * g_special));
64+
65+ // 3. 计算指数项和余弦项
66+ double half_L = L / 2.0 ;
67+ double cos_term = std::cos (g_special * half_L);
68+ double exp_term = std::exp (-g_planar * half_L);
69+
70+ // 4. 组合
71+ // 注意负号
72+ return -coulomb_term * cos_term * exp_term;
73+ }
0 commit comments