void update_adress_weights_atom_per_atom( int cg0, int cg1, t_block * cgs, rvec x[], t_forcerec * fr, t_mdatoms * mdatoms, t_pbc * pbc) { int icg, k, k0, k1; atom_id * cgindex; int adresstype; real adressr, adressw; rvec * ref; real * wf; int n_hyb, n_ex, n_cg; n_hyb = 0; n_cg = 0; n_ex = 0; adresstype = fr->adress_type; adressr = fr->adress_ex_width; adressw = fr->adress_hy_width; wf = mdatoms->wf; ref = &(fr->adress_refs); cgindex = cgs->index; /* Weighting function is determined for each atom individually. * This is an approximation * as in the theory requires an interpolation based on the center of masses. * Should be used with caution */ for (icg = cg0; (icg < cg1); icg++) { k0 = cgindex[icg]; k1 = cgindex[icg + 1]; for (k = (k0); (k < k1); k++) { wf[k] = adress_weight(x[k], adresstype, adressr, adressw, ref, pbc, fr); if (wf[k] == 0) { n_cg++; } else if (wf[k] == 1) { n_ex++; } else { n_hyb++; } } } }
void update_adress_weights_atom(int cg0, int cg1, t_block * cgs, rvec x[], t_forcerec * fr, t_mdatoms * mdatoms, t_pbc * pbc) { int icg,k,k0,k1; atom_id * cgindex; int adresstype; real adressr,adressw; rvec * ref; rvec * ref_2; real * massT; real * wf; real * wfprime; adresstype = fr->adress_type; adressr = fr->adress_ex_width; adressw = fr->adress_hy_width; massT = mdatoms->massT; wf = mdatoms->wf; ref = &(fr->adress_refs); ref_2 = &(fr->adress_refs_2); cgindex = cgs->index; wfprime = mdatoms->wfprime; /* Only use first atom in charge group. * We still can't be sure that the vsite and constructing * atoms are on the same processor, so we must calculate * in the same way as com adress. */ for(icg=cg0; (icg<cg1); icg++) { k0 = cgindex[icg]; k1 = cgindex[icg+1]; wf[k0] = adress_weight(x[k0],adresstype,adressr,adressw,ref,ref_2,pbc,fr); wfprime[k0] = Dadress_weight(x[k0],adresstype,adressr,adressw,ref,ref_2,pbc,fr); /* Set wf of all atoms in charge group equal to wf of first atom in charge group*/ for(k=(k0+1); (k<k1); k++) { wf[k] = wf[k0]; wfprime[k] = wfprime[k0]; } } }
void update_adress_weights_cog(t_iparams ip[], t_ilist ilist[], rvec x[], t_forcerec * fr, t_mdatoms * mdatoms, t_pbc * pbc) { int i, j, k, nr, nra, inc; int ftype, adresstype; t_iatom avsite, ai, aj, ak, al; t_iatom * ia; real adressr, adressw; rvec * ref; real * wf; int n_hyb, n_ex, n_cg; adresstype = fr->adress_type; adressr = fr->adress_ex_width; adressw = fr->adress_hy_width; wf = mdatoms->wf; ref = &(fr->adress_refs); n_hyb = 0; n_cg = 0; n_ex = 0; /* Since this is center of geometry AdResS, we know the vsite * is in the same charge group node as the constructing atoms. * Loop over vsite types, calculate the weight of the vsite, * then assign that weight to the constructing atoms. */ for (ftype = 0; (ftype < F_NRE); ftype++) { if (interaction_function[ftype].flags & IF_VSITE) { nra = interaction_function[ftype].nratoms; nr = ilist[ftype].nr; ia = ilist[ftype].iatoms; for (i = 0; (i < nr); ) { /* The vsite and first constructing atom */ avsite = ia[1]; ai = ia[2]; wf[avsite] = adress_weight(x[avsite], adresstype, adressr, adressw, ref, pbc, fr); wf[ai] = wf[avsite]; if (wf[ai] == 0) { n_cg++; } else if (wf[ai] == 1) { n_ex++; } else { n_hyb++; } /* Assign the vsite wf to rest of constructing atoms depending on type */ inc = nra+1; switch (ftype) { case F_VSITE2: aj = ia[3]; wf[aj] = wf[avsite]; break; case F_VSITE3: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; break; case F_VSITE3FD: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; break; case F_VSITE3FAD: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; break; case F_VSITE3OUT: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; break; case F_VSITE4FD: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; al = ia[5]; wf[al] = wf[avsite]; break; case F_VSITE4FDN: aj = ia[3]; wf[aj] = wf[avsite]; ak = ia[4]; wf[ak] = wf[avsite]; al = ia[5]; wf[al] = wf[avsite]; break; case F_VSITEN: inc = 3*ip[ia[0]].vsiten.n; for (j = 3; j < inc; j += 3) { ai = ia[j+2]; wf[ai] = wf[avsite]; } break; default: gmx_fatal(FARGS, "No such vsite type %d in %s, line %d", ftype, __FILE__, __LINE__); } /* Increment loop variables */ i += inc; ia += inc; } } } }
void update_adress_weights_com(FILE gmx_unused * fplog, int cg0, int cg1, t_block * cgs, rvec x[], t_forcerec * fr, t_mdatoms * mdatoms, t_pbc * pbc) { int icg, k, k0, k1, d; real nrcg, inv_ncg, mtot, inv_mtot; atom_id * cgindex; rvec ix; int adresstype; real adressr, adressw; rvec * ref; real * massT; real * wf; int n_hyb, n_ex, n_cg; n_hyb = 0; n_cg = 0; n_ex = 0; adresstype = fr->adress_type; adressr = fr->adress_ex_width; adressw = fr->adress_hy_width; massT = mdatoms->massT; wf = mdatoms->wf; ref = &(fr->adress_refs); /* Since this is center of mass AdResS, the vsite is not guaranteed * to be on the same node as the constructing atoms. Therefore we * loop over the charge groups, calculate their center of mass, * then use this to calculate wf for each atom. This wastes vsite * construction, but it's the only way to assure that the explicit * atoms have the same wf as their vsite. */ #ifdef DEBUG fprintf(fplog, "Calculating center of mass for charge groups %d to %d\n", cg0, cg1); #endif cgindex = cgs->index; /* Compute the center of mass for all charge groups */ for (icg = cg0; (icg < cg1); icg++) { k0 = cgindex[icg]; k1 = cgindex[icg+1]; nrcg = k1-k0; if (nrcg == 1) { wf[k0] = adress_weight(x[k0], adresstype, adressr, adressw, ref, pbc, fr); if (wf[k0] == 0) { n_cg++; } else if (wf[k0] == 1) { n_ex++; } else { n_hyb++; } } else { mtot = 0.0; for (k = k0; (k < k1); k++) { mtot += massT[k]; } if (mtot > 0.0) { inv_mtot = 1.0/mtot; clear_rvec(ix); for (k = k0; (k < k1); k++) { for (d = 0; (d < DIM); d++) { ix[d] += x[k][d]*massT[k]; } } for (d = 0; (d < DIM); d++) { ix[d] *= inv_mtot; } } /* Calculate the center of gravity if the charge group mtot=0 (only vsites) */ else { inv_ncg = 1.0/nrcg; clear_rvec(ix); for (k = k0; (k < k1); k++) { for (d = 0; (d < DIM); d++) { ix[d] += x[k][d]; } } for (d = 0; (d < DIM); d++) { ix[d] *= inv_ncg; } } /* Set wf of all atoms in charge group equal to wf of com */ wf[k0] = adress_weight(ix, adresstype, adressr, adressw, ref, pbc, fr); if (wf[k0] == 0) { n_cg++; } else if (wf[k0] == 1) { n_ex++; } else { n_hyb++; } for (k = (k0+1); (k < k1); k++) { wf[k] = wf[k0]; } } } }