00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <stdio.h>
00021 #include <math.h>
00022 #include "Measure.h"
00023 #include "FastPBC.h"
00024
00025 #ifdef VMDOPENACC
00026 #include <accelmath.h>
00027 #endif
00028
00033
00034
00035 #ifndef VMDCUDA
00036 void fpbc_exec_unwrap(Molecule* mol, int first, int last, int sellen, int* indexlist) {
00037 fpbc_exec_unwrap_cpu(mol, first, last, sellen, indexlist);
00038 }
00039
00040 void fpbc_exec_wrapatomic(Molecule* mol, int first, int last, int sellen, int* indexlist,
00041 float* weights, AtomSel* csel, float* center) {
00042 fpbc_exec_wrapatomic_cpu(mol, first, last, sellen, indexlist, weights, csel, center);
00043 }
00044
00045 void fpbc_exec_wrapcompound(Molecule* mol, int first, int last, int fnum, int *compoundmap, int sellen, int* indexlist,
00046 float* weights, AtomSel* csel, float* center, float* massarr) {
00047 fpbc_exec_wrapcompound_cpu(mol, first, last, fnum, compoundmap, sellen, indexlist, weights, csel, center, massarr);
00048 }
00049
00050 void fpbc_exec_join(Molecule* mol, int first, int last, int fnum, int *compoundmap, int sellen, int* indexlist) {
00051 fpbc_exec_join_cpu(mol, first, last, fnum, compoundmap, sellen, indexlist);
00052 }
00053
00054 void fpbc_exec_recenter(Molecule* mol, int first, int last, int csellen, int* cindexlist, int fnum, int *compoundmap, int sellen, int* indexlist, float* weights, AtomSel* csel, float* massarr) {
00055 fpbc_exec_recenter_cpu(mol, first, last, csellen, cindexlist, fnum, compoundmap, sellen, indexlist, weights, csel, massarr);
00056 }
00057 #endif
00058
00059 void fpbc_exec_wrapatomic_cpu(Molecule* mol, int first, int last, int sellen, int* indexlist,
00060 float* weights, AtomSel* csel, float* center) {
00061 int f, i, j, k;
00062 float boxsize[3];
00063 float invboxsize[3];
00064 for (f=first; f<=last; f++) {
00065 Timestep *ts = mol->get_frame(f);
00066 boxsize[0] = ts->a_length;
00067 boxsize[1] = ts->b_length;
00068 boxsize[2] = ts->c_length;
00069 for (j=0; j < 3; j++) {
00070 invboxsize[j] = 1.0f/boxsize[j];
00071 }
00072
00073 if (csel != NULL) {
00074 measure_center(csel, ts->pos, weights, center);
00075 }
00076 for (k=0; k<sellen; k++) {
00077 i = indexlist[k];
00078 for (j=0; j < 3; j++) {
00079
00080 ts->pos[i*3+j] = ts->pos[i*3+j] - (roundf((ts->pos[i*3+j] - center[j]) * invboxsize[j]) * boxsize[j]);
00081 }
00082 }
00083 }
00084 }
00085
00086
00087 void fpbc_exec_wrapcompound_cpu(Molecule* mol, int first, int last, int fnum, int *compoundmap, int sellen, int* indexlist,
00088 float* weights, AtomSel* csel, float* center, float* massarr) {
00089 int f, i, j, k, l;
00090 float boxsize[3];
00091 float invboxsize[3];
00092 for (f=first; f<=last; f++) {
00093 Timestep *ts = mol->get_frame(f);
00094 boxsize[0] = ts->a_length;
00095 boxsize[1] = ts->b_length;
00096 boxsize[2] = ts->c_length;
00097 for (j=0; j < 3; j++) {
00098 invboxsize[j] = 1.0f/boxsize[j];
00099 }
00100
00101 if (csel != NULL) {
00102 measure_center(csel, ts->pos, weights, center);
00103 }
00104 for (l = 0; l < fnum; l++) {
00105 int lowbound = compoundmap[l];
00106 int highbound = compoundmap[l+1];
00107
00108 float cmass = 0;
00109 float ccenter[3] = {0,0,0};
00110
00111 for (k = lowbound; k < highbound; k++ ) {
00112 i = indexlist[k];
00113 for (j=0; j < 3; j++) {
00114 ccenter[j] += massarr[i] * (ts->pos[i*3+j]);
00115 }
00116 cmass += massarr[i];
00117 }
00118 cmass = 1.0f / cmass;
00119
00120 for (j=0; j < 3; j++) {
00121 ccenter[j] *= cmass;
00122 }
00123
00124 for (k = lowbound; k < highbound; k++ ) {
00125 i = indexlist[k];
00126 for (j=0; j < 3; j++) {
00127 ts->pos[i*3+j] = ts->pos[i*3+j] - (roundf((ccenter[j] - center[j]) * invboxsize[j]) * boxsize[j]);
00128 }
00129 }
00130 }
00131 }
00132 }
00133
00134
00135 void fpbc_exec_join_cpu(Molecule* mol, int first, int last, int fnum, int *compoundmap, int sellen, int* indexlist) {
00136 int f, i, j, k, l;
00137 float boxsize[3];
00138 float invboxsize[3];
00139 float *pos;
00140 Timestep *ts;
00141 #pragma acc data copyin (indexlist[sellen], compoundmap[fnum+1])
00142 {
00143
00144 for (f=first; f<=last; f++) {
00145
00146 ts = mol->get_frame(f);
00147 boxsize[0] = ts->a_length;
00148 boxsize[1] = ts->b_length;
00149 boxsize[2] = ts->c_length;
00150 pos = ts->pos;
00151 #pragma acc data copy(pos[3*mol->nAtoms]) copyin(boxsize[3]) create(invboxsize[3]) async(f%2)
00152 {
00153 #pragma acc kernels private(i, j, k, l) async(f%2)
00154 {
00155
00156 for (int q=0; q < 3; q++) {
00157 invboxsize[q] = 1.0f/boxsize[q];
00158 }
00159 #pragma acc loop independent private(i, j, k, l)
00160 for (l = 0; l < fnum; l++) {
00161 float ccenter[3];
00162 int lowbound = compoundmap[l];
00163 int highbound = compoundmap[l+1];
00164 i = indexlist[lowbound];
00165
00166 for (j=0; j < 3; j++) {
00167 ccenter[j] = pos[(i+((highbound-lowbound)/2))*3+j];
00168 }
00169
00170 for (k = lowbound; k < highbound; k++ ) {
00171 i = indexlist[k];
00172 for (j=0; j < 3; j++) {
00173 pos[i*3+j] = pos[i*3+j] - (rintf((pos[i*3+j] - ccenter[j]) * invboxsize[j]) * boxsize[j]);
00174 }
00175 }
00176 }
00177 }
00178 }
00179 }
00180 #pragma acc wait
00181 }
00182 }
00183
00184
00185 void fpbc_exec_unwrap_cpu(Molecule* mol, int first, int last, int sellen, int* indexlist) {
00186 Timestep *ts, *prev;
00187 int f, i, j, idx;
00188 float boxsize[3];
00189 float oldboxsize[3];
00190 float invboxsize[3];
00191 float *prevw = new float[3*sellen];
00192 float curw;
00193 float disp;
00194
00195
00196 ts = mol->get_frame(first);
00197 for (i=0; i<sellen; i++) {
00198 for (j=0; j<3; j++) {
00199 prevw[3*i+j] = ts->pos[indexlist[i]*3+j];
00200 }
00201 }
00202
00203 for (f=first+1; f<=last; f++) {
00204 ts = mol->get_frame(f);
00205 prev = mol->get_frame(f-1);
00206 boxsize[0] = ts->a_length;
00207 boxsize[1] = ts->b_length;
00208 boxsize[2] = ts->c_length;
00209 oldboxsize[0] = prev->a_length;
00210 oldboxsize[1] = prev->b_length;
00211 oldboxsize[2] = prev->c_length;
00212 for (j=0; j < 3; j++) {
00213 invboxsize[j] = 1.0f/boxsize[j];
00214 }
00215 for (i=0; i<sellen; i++) {
00216 idx = indexlist[i];
00217 for (j=0; j < 3; j++) {
00218 disp = ts->pos[idx*3+j] - prevw[3*i+j];
00219 curw = ts->pos[idx*3+j];
00220 ts->pos[idx*3+j] = prev->pos[idx*3+j] + disp
00221 -(floorf(disp * invboxsize[j] + 0.5f) * boxsize[j])
00222 -(floorf(((prevw[3*i+j]-prev->pos[idx*3+j])/oldboxsize[j])+0.5f)*(boxsize[j]-oldboxsize[j]));
00223 prevw[3*i+j] = curw;
00224 }
00225 }
00226 }
00227 delete [] prevw;
00228 }
00229
00230
00231 void fpbc_exec_recenter_cpu(Molecule* mol, int first, int last, int csellen, int* cindexlist, int fnum, int *compoundmap, int sellen, int* indexlist, float* weights, AtomSel* csel, float* massarr) {
00232 float center[3];
00233
00234 fpbc_exec_unwrap_cpu(mol, first, last, csellen, cindexlist);
00235 if (fnum)
00236 fpbc_exec_wrapcompound_cpu(mol, first, last, fnum, compoundmap, sellen, indexlist, weights, csel, ¢er[0], massarr);
00237 else
00238 fpbc_exec_wrapatomic_cpu(mol, first, last, sellen, indexlist, weights, csel, ¢er[0]);
00239 }
00240
00241
00242
00243