static void lo_fcv(int i0,int i1,int g0, real x[],real f[],tensor vir, int is[],real box[], bool bTriclinic) { int i,i3,gg,g3,tx,ty,tz; real xx,yy,zz; real dvxx=0,dvxy=0,dvxz=0,dvyx=0,dvyy=0,dvyz=0,dvzx=0,dvzy=0,dvzz=0; if(bTriclinic) { for(i=i0,gg=g0; (i<i1); i++,gg++) { i3=DIM*i; g3=DIM*gg; tx=is[g3+XX]; ty=is[g3+YY]; tz=is[g3+ZZ]; xx=x[i3+XX]-tx*box[XXXX]-ty*box[YYXX]-tz*box[ZZXX]; dvxx+=xx*f[i3+XX]; dvxy+=xx*f[i3+YY]; dvxz+=xx*f[i3+ZZ]; yy=x[i3+YY]-ty*box[YYYY]-tz*box[ZZYY]; dvyx+=yy*f[i3+XX]; dvyy+=yy*f[i3+YY]; dvyz+=yy*f[i3+ZZ]; zz=x[i3+ZZ]-tz*box[ZZZZ]; dvzx+=zz*f[i3+XX]; dvzy+=zz*f[i3+YY]; dvzz+=zz*f[i3+ZZ]; } } else { for(i=i0,gg=g0; (i<i1); i++,gg++) { i3=DIM*i; g3=DIM*gg; tx=is[g3+XX]; ty=is[g3+YY]; tz=is[g3+ZZ]; xx=x[i3+XX]-tx*box[XXXX]; dvxx+=xx*f[i3+XX]; dvxy+=xx*f[i3+YY]; dvxz+=xx*f[i3+ZZ]; yy=x[i3+YY]-ty*box[YYYY]; dvyx+=yy*f[i3+XX]; dvyy+=yy*f[i3+YY]; dvyz+=yy*f[i3+ZZ]; zz=x[i3+ZZ]-tz*box[ZZZZ]; dvzx+=zz*f[i3+XX]; dvzy+=zz*f[i3+YY]; dvzz+=zz*f[i3+ZZ]; } } upd_vir(vir[XX],dvxx,dvxy,dvxz); upd_vir(vir[YY],dvyx,dvyy,dvyz); upd_vir(vir[ZZ],dvzx,dvzy,dvzz); }
static void lo_fcv2(int i0,int i1, rvec x[],rvec f[],tensor vir, ivec is[],matrix box, bool bTriclinic) { int i,gg,tx,ty,tz; real xx,yy,zz; real dvxx=0,dvxy=0,dvxz=0,dvyx=0,dvyy=0,dvyz=0,dvzx=0,dvzy=0,dvzz=0; if(bTriclinic) { for(i=i0,gg=0; (i<i1); i++,gg++) { tx=is[gg][XX]; ty=is[gg][YY]; tz=is[gg][ZZ]; xx=x[i][XX]-tx*box[XX][XX]-ty*box[YY][XX]-tz*box[ZZ][XX]; dvxx+=xx*f[i][XX]; dvxy+=xx*f[i][YY]; dvxz+=xx*f[i][ZZ]; yy=x[i][YY]-ty*box[YY][YY]-tz*box[ZZ][YY]; dvyx+=yy*f[i][XX]; dvyy+=yy*f[i][YY]; dvyz+=yy*f[i][ZZ]; zz=x[i][ZZ]-tz*box[ZZ][ZZ]; dvzx+=zz*f[i][XX]; dvzy+=zz*f[i][YY]; dvzz+=zz*f[i][ZZ]; } } else { for(i=i0,gg=0; (i<i1); i++,gg++) { tx=is[gg][XX]; ty=is[gg][YY]; tz=is[gg][ZZ]; xx=x[i][XX]-tx*box[XX][XX]; dvxx+=xx*f[i][XX]; dvxy+=xx*f[i][YY]; dvxz+=xx*f[i][ZZ]; yy=x[i][YY]-ty*box[YY][YY]; dvyx+=yy*f[i][XX]; dvyy+=yy*f[i][YY]; dvyz+=yy*f[i][ZZ]; zz=x[i][ZZ]-tz*box[ZZ][ZZ]; dvzx+=zz*f[i][XX]; dvzy+=zz*f[i][YY]; dvzz+=zz*f[i][ZZ]; } } upd_vir(vir[XX],dvxx,dvxy,dvxz); upd_vir(vir[YY],dvyx,dvyy,dvyz); upd_vir(vir[ZZ],dvzx,dvzy,dvzz); }
void calc_vir(int nxf, rvec x[], rvec f[], tensor vir, gmx_bool bScrewPBC, matrix box) { int i; double dvxx = 0, dvxy = 0, dvxz = 0, dvyx = 0, dvyy = 0, dvyz = 0, dvzx = 0, dvzy = 0, dvzz = 0; #pragma omp parallel for num_threads(gmx_omp_nthreads_get(emntDefault)) \ schedule(static) \ reduction(+: dvxx, dvxy, dvxz, dvyx, dvyy, dvyz, dvzx, dvzy, dvzz) for (i = 0; i < nxf; i++) { dvxx += x[i][XX]*f[i][XX]; dvxy += x[i][XX]*f[i][YY]; dvxz += x[i][XX]*f[i][ZZ]; dvyx += x[i][YY]*f[i][XX]; dvyy += x[i][YY]*f[i][YY]; dvyz += x[i][YY]*f[i][ZZ]; dvzx += x[i][ZZ]*f[i][XX]; dvzy += x[i][ZZ]*f[i][YY]; dvzz += x[i][ZZ]*f[i][ZZ]; if (bScrewPBC) { int isx = IS2X(i); /* We should correct all odd x-shifts, but the range of isx is -2 to 2 */ if (isx == 1 || isx == -1) { dvyy += box[YY][YY]*f[i][YY]; dvyz += box[YY][YY]*f[i][ZZ]; dvzy += box[ZZ][ZZ]*f[i][YY]; dvzz += box[ZZ][ZZ]*f[i][ZZ]; } } } upd_vir(vir[XX], dvxx, dvxy, dvxz); upd_vir(vir[YY], dvyx, dvyy, dvyz); upd_vir(vir[ZZ], dvzx, dvzy, dvzz); }
void calc_vir(int nxf, rvec x[], rvec f[], tensor vir, gmx_bool bScrewPBC, matrix box) { int i, isx; double dvxx = 0, dvxy = 0, dvxz = 0, dvyx = 0, dvyy = 0, dvyz = 0, dvzx = 0, dvzy = 0, dvzz = 0; for (i = 0; (i < nxf); i++) { dvxx += x[i][XX]*f[i][XX]; dvxy += x[i][XX]*f[i][YY]; dvxz += x[i][XX]*f[i][ZZ]; dvyx += x[i][YY]*f[i][XX]; dvyy += x[i][YY]*f[i][YY]; dvyz += x[i][YY]*f[i][ZZ]; dvzx += x[i][ZZ]*f[i][XX]; dvzy += x[i][ZZ]*f[i][YY]; dvzz += x[i][ZZ]*f[i][ZZ]; if (bScrewPBC) { isx = IS2X(i); /* We should correct all odd x-shifts, but the range of isx is -2 to 2 */ if (isx == 1 || isx == -1) { dvyy += box[YY][YY]*f[i][YY]; dvyz += box[YY][YY]*f[i][ZZ]; dvzy += box[ZZ][ZZ]*f[i][YY]; dvzz += box[ZZ][ZZ]*f[i][ZZ]; } } } upd_vir(vir[XX], dvxx, dvxy, dvxz); upd_vir(vir[YY], dvyx, dvyy, dvyz); upd_vir(vir[ZZ], dvzx, dvzy, dvzz); }
void calc_vir(FILE *log,int nxf,rvec x[],rvec f[],tensor vir) { int i; real dvxx=0,dvxy=0,dvxz=0,dvyx=0,dvyy=0,dvyz=0,dvzx=0,dvzy=0,dvzz=0; for(i=0; (i<nxf); i++) { dvxx+=x[i][XX]*f[i][XX]; dvxy+=x[i][XX]*f[i][YY]; dvxz+=x[i][XX]*f[i][ZZ]; dvyx+=x[i][YY]*f[i][XX]; dvyy+=x[i][YY]*f[i][YY]; dvyz+=x[i][YY]*f[i][ZZ]; dvzx+=x[i][ZZ]*f[i][XX]; dvzy+=x[i][ZZ]*f[i][YY]; dvzz+=x[i][ZZ]*f[i][ZZ]; } upd_vir(vir[XX],dvxx,dvxy,dvxz); upd_vir(vir[YY],dvyx,dvyy,dvyz); upd_vir(vir[ZZ],dvzx,dvzy,dvzz); }
void calc_vir(int nxf, const rvec x[], const rvec f[], tensor vir, bool bScrewPBC, const matrix box) { matrix x_times_f; int nthreads = gmx_omp_nthreads_get_simple_rvec_task(emntDefault, nxf*9); GMX_ASSERT(nthreads >= 1, "Avoids uninitialized x_times_f (warning)"); if (nthreads == 1) { calc_x_times_f(nxf, x, f, bScrewPBC, box, x_times_f); } else { /* Use a buffer on the stack for storing thread-local results. * We use 2 extra elements (=18 reals) per thread to separate thread * local data by at least a cache line. Element 0 is not used. */ matrix xf_buf[GMX_OPENMP_MAX_THREADS*3]; #pragma omp parallel for num_threads(nthreads) schedule(static) for (int thread = 0; thread < nthreads; thread++) { int start = (nxf*thread)/nthreads; int end = std::min(nxf*(thread + 1)/nthreads, nxf); calc_x_times_f(end - start, x + start, f + start, bScrewPBC, box, thread == 0 ? x_times_f : xf_buf[thread*3]); } for (int thread = 1; thread < nthreads; thread++) { m_add(x_times_f, xf_buf[thread*3], x_times_f); } } for (int d = 0; d < DIM; d++) { upd_vir(vir[d], x_times_f[d][XX], x_times_f[d][YY], x_times_f[d][ZZ]); } }