atmforce.cc 7.9 KB
Newer Older
1
2
3
4
5
KERNEL void hybridForce(int numParticles,
                        int paddedNumParticles,
                        GLOBAL mm_long* RESTRICT force,
                        GLOBAL mm_long* RESTRICT force0,
                        GLOBAL mm_long* RESTRICT force1,
6
7
                        GLOBAL mm_long* RESTRICT dforce0,
                        GLOBAL mm_long* RESTRICT dforce1,
8
9
10
                        GLOBAL int* RESTRICT invAtomOrder,
                        GLOBAL int* RESTRICT inner0InvAtomOrder,
                        GLOBAL int* RESTRICT inner1InvAtomOrder,
11
12
13
                        real dEdu0,
                        real dEdu1) {
    for (int i = GLOBAL_ID; i < numParticles; i += GLOBAL_SIZE) {
14
15
16
        int index = invAtomOrder[i];
        int index0 = inner0InvAtomOrder[i];
        int index1 = inner1InvAtomOrder[i];
17
18
19
20
21
22
23
24
25
        mm_long fx0 = force0[index0]+dforce0[index];
        mm_long fy0 = force0[index0+paddedNumParticles]+dforce0[index+paddedNumParticles];
        mm_long fz0 = force0[index0+paddedNumParticles*2]+dforce0[index+paddedNumParticles*2];
        mm_long fx1 = force1[index1]+dforce1[index];
        mm_long fy1 = force1[index1+paddedNumParticles]+dforce1[index+paddedNumParticles];
        mm_long fz1 = force1[index1+paddedNumParticles*2]+dforce1[index+paddedNumParticles*2];
        force[index]                      += (mm_long) (dEdu0*fx0 + dEdu1*fx1);
        force[index+paddedNumParticles]   += (mm_long) (dEdu0*fy0 + dEdu1*fy1);
        force[index+paddedNumParticles*2] += (mm_long) (dEdu0*fz0 + dEdu1*fz1);
26
27
28
    }
}

29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
KERNEL void setDisplacements(int numParticles,
                             GLOBAL real4* RESTRICT posq,
                         GLOBAL real4* RESTRICT displacement0,
                             GLOBAL real4* RESTRICT displacement1,
                             GLOBAL int4* displParticles,
                             GLOBAL int* RESTRICT atomOrder,
                             GLOBAL int* RESTRICT invAtomOrder,
                             GLOBAL real4* RESTRICT displ0,
                             GLOBAL real4* RESTRICT displ1) {
    for (int index = GLOBAL_ID; index < numParticles; index += GLOBAL_SIZE) {
        int atom = atomOrder[index];
        int pj1 = displParticles[atom].x;
        int pi1 = displParticles[atom].y;
        int pj0 = displParticles[atom].z;
        int pi0 = displParticles[atom].w;
        if (pj1 >= 0 && pi1 >= 0) {
            // variable system coordinate displacements
            int indexj1 = invAtomOrder[pj1];
            int indexi1 = invAtomOrder[pi1];
            displ1[atom] = make_real4((real) posq[indexj1].x- posq[indexi1].x,
                                      (real) posq[indexj1].y- posq[indexi1].y,
                                      (real) posq[indexj1].z- posq[indexi1].z, (real) 0);
            if (pj0 >= 0 && pi0 >= 0) {
                int indexj0 = invAtomOrder[pj0];
                int indexi0 = invAtomOrder[pi0];
                displ0[atom] = make_real4((real) posq[indexj0].x - posq[indexi0].x,
                                          (real) posq[indexj0].y - posq[indexi0].y,
                                          (real) posq[indexj0].z - posq[indexi0].z, (real) 0);
            }
            else {
                displ0[atom] = make_real4((real) 0, (real) 0, (real) 0, (real) 0);
            }
        }
        else {
            //fixed lab frame displacement
            displ1[atom] = displacement1[atom];
            displ0[atom] = displacement0[atom];
        }
    }
}

//reset variable displacement forces
KERNEL void resetDisplForce(int numParticles,
                            int paddedNumParticles,
                            GLOBAL mm_ulong* RESTRICT dforce0,
                            GLOBAL mm_ulong* RESTRICT dforce1) {
    mm_ulong zero = 0;
    for (int index = GLOBAL_ID; index < numParticles; index += GLOBAL_SIZE) {
        dforce0[index]                      = zero;
        dforce0[index+paddedNumParticles]   = zero;
        dforce0[index+paddedNumParticles*2] = zero;
        dforce1[index]                      = zero;
        dforce1[index+paddedNumParticles]   = zero;
        dforce1[index+paddedNumParticles*2] = zero;
    }
}

//add forces due to variable displacements
KERNEL void displForce(int numParticles,
                       int paddedNumParticles,
                       GLOBAL mm_long* RESTRICT force0,
                       GLOBAL mm_long* RESTRICT force1,
                       GLOBAL mm_long* RESTRICT dforce0,
                       GLOBAL mm_long* RESTRICT dforce1,
                       GLOBAL int4* displParticles,
                       GLOBAL int* RESTRICT atomOrder,
                       GLOBAL int* RESTRICT invAtomOrder,
                       GLOBAL int* RESTRICT inner0InvAtomOrder,
                       GLOBAL int* RESTRICT inner1InvAtomOrder) {
    GLOBAL mm_ulong* df0 = (GLOBAL mm_ulong*) dforce0;
    GLOBAL mm_ulong* df1 = (GLOBAL mm_ulong*) dforce1;
    for (int index = GLOBAL_ID; index < numParticles; index += GLOBAL_SIZE) {
        int atom = atomOrder[index];
        int pj1 = displParticles[atom].x;
        int pi1 = displParticles[atom].y;
        int pj0 = displParticles[atom].z;
        int pi0 = displParticles[atom].w;
        int index0 = inner0InvAtomOrder[atom];
        int index1 = inner1InvAtomOrder[atom];
        if (pj1 >= 0 && pi1 >= 0) {
            int j1 = invAtomOrder[pj1];
            int i1 = invAtomOrder[pi1];
            ATOMIC_ADD(&df1[j1], (mm_ulong) force1[index1]);
            ATOMIC_ADD(&df1[j1+paddedNumParticles], (mm_ulong) force1[index1+paddedNumParticles]);
            ATOMIC_ADD(&df1[j1+paddedNumParticles*2], (mm_ulong) force1[index1+paddedNumParticles*2]);
            ATOMIC_ADD(&df1[i1], (mm_ulong) -force1[index1]);
            ATOMIC_ADD(&df1[i1+paddedNumParticles], (mm_ulong) -force1[index1+paddedNumParticles]);
            ATOMIC_ADD(&df1[i1+paddedNumParticles*2],(mm_ulong)  -force1[index1+paddedNumParticles*2]);
        }
        if (pj0 >= 0 && pi0 >= 0) {
            int j0 = invAtomOrder[pj0];
            int i0 = invAtomOrder[pi0];
            ATOMIC_ADD(&df0[j0], (mm_ulong) force0[index0]);
            ATOMIC_ADD(&df0[j0+paddedNumParticles], (mm_ulong) force0[index0+paddedNumParticles]);
            ATOMIC_ADD(&df0[j0+paddedNumParticles*2],(mm_ulong)  force0[index0+paddedNumParticles*2]);
            ATOMIC_ADD(&df0[i0], (mm_ulong) -force0[index0]);
            ATOMIC_ADD(&df0[i0+paddedNumParticles], (mm_ulong) -force0[index0+paddedNumParticles]);
            ATOMIC_ADD(&df0[i0+paddedNumParticles*2], (mm_ulong) -force0[index0+paddedNumParticles*2]);
        }
    }
}



133
134
135
136
KERNEL void copyState(int numParticles,
                      GLOBAL real4* RESTRICT posq,
                      GLOBAL real4* RESTRICT posq0,
                      GLOBAL real4* RESTRICT posq1,
137
138
                      GLOBAL real4* RESTRICT displ0,
                      GLOBAL real4* RESTRICT displ1,
139
140
141
                      GLOBAL int* RESTRICT atomOrder,
                      GLOBAL int* RESTRICT inner0InvAtomOrder,
                      GLOBAL int* RESTRICT inner1InvAtomOrder
142
143
144
145
146
147
148
149
#ifdef USE_MIXED_PRECISION
                      ,
                      GLOBAL real4* RESTRICT posqCorrection,
                      GLOBAL real4* RESTRICT posq0Correction,
                      GLOBAL real4* RESTRICT posq1Correction
#endif
                    ) {
    for (int i = GLOBAL_ID; i < numParticles; i += GLOBAL_SIZE) {
150
151
152
153
154
        int atom = atomOrder[i];
        int index0 = inner0InvAtomOrder[atom];
        int index1 = inner1InvAtomOrder[atom];
        real4 p0 = posq[i] + make_real4((real) displ0[atom].x, (real) displ0[atom].y, (real) displ0[atom].z, 0);
        real4 p1 = posq[i] + make_real4((real) displ1[atom].x, (real) displ1[atom].y, (real) displ1[atom].z, 0);
155
156
        p0.w = posq0[i].w;
        p1.w = posq1[i].w;
157
158
        posq0[index0] = p0;
        posq1[index1] = p1;
159
#ifdef USE_MIXED_PRECISION
160
161
        posq0Correction[index0] = posqCorrection[i];
        posq1Correction[index1] = posqCorrection[i];
162
163
164
#endif
    }
}