int ComputeBondLocal::compute_bonds(int flag) { int i,m,n,nb,atom1,atom2,imol,iatom,btype; tagint tagprev; double dx,dy,dz,rsq; double mass1,mass2,masstotal,invmasstotal; double xcm[3],vcm[3]; double delr1[3],delr2[3],delv1[3],delv2[3]; double r12[3],vpar1,vpar2; double vvib,vrotsq; double inertia,omegasq; double mvv2e; double engpot,engtrans,engvib,engrot,fbond; double *ptr; double **x = atom->x; double **v = atom->v; int *type = atom->type; double *mass = atom->mass; double *rmass = atom->rmass; tagint *tag = atom->tag; int *num_bond = atom->num_bond; tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; int *mask = atom->mask; int *molindex = atom->molindex; int *molatom = atom->molatom; Molecule **onemols = atom->avec->onemols; int nlocal = atom->nlocal; int newton_bond = force->newton_bond; int molecular = atom->molecular; Bond *bond = force->bond; // communicate ghost velocities if needed if (ghostvelflag && !initflag) comm->forward_comm_compute(this); // loop over all atoms and their bonds m = n = 0; for (atom1 = 0; atom1 < nlocal; atom1++) { if (!(mask[atom1] & groupbit)) continue; if (molecular == 1) nb = num_bond[atom1]; else { if (molindex[atom1] < 0) continue; imol = molindex[atom1]; iatom = molatom[atom1]; nb = onemols[imol]->num_bond[iatom]; } for (i = 0; i < nb; i++) { if (molecular == 1) { btype = bond_type[atom1][i]; atom2 = atom->map(bond_atom[atom1][i]); } else { tagprev = tag[atom1] - iatom - 1; btype = onemols[imol]->bond_type[iatom][i]; atom2 = atom->map(onemols[imol]->bond_atom[iatom][i]+tagprev); } if (atom2 < 0 || !(mask[atom2] & groupbit)) continue; if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; if (btype == 0) continue; if (!flag) { m++; continue; } dx = x[atom1][0] - x[atom2][0]; dy = x[atom1][1] - x[atom2][1]; dz = x[atom1][2] - x[atom2][2]; domain->minimum_image(dx,dy,dz); rsq = dx*dx + dy*dy + dz*dz; if (btype == 0) { engpot = fbond = 0.0; engvib = engrot = engtrans = omegasq = vvib = 0.0; } else { if (singleflag) engpot = bond->single(btype,rsq,atom1,atom2,fbond); if (velflag) { if (rmass) { mass1 = rmass[atom1]; mass2 = rmass[atom2]; } else { mass1 = mass[type[atom1]]; mass2 = mass[type[atom2]]; } masstotal = mass1+mass2; invmasstotal = 1.0 / (masstotal); xcm[0] = (mass1*x[atom1][0] + mass2*x[atom2][0]) * invmasstotal; xcm[1] = (mass1*x[atom1][1] + mass2*x[atom2][1]) * invmasstotal; xcm[2] = (mass1*x[atom1][2] + mass2*x[atom2][2]) * invmasstotal; vcm[0] = (mass1*v[atom1][0] + mass2*v[atom2][0]) * invmasstotal; vcm[1] = (mass1*v[atom1][1] + mass2*v[atom2][1]) * invmasstotal; vcm[2] = (mass1*v[atom1][2] + mass2*v[atom2][2]) * invmasstotal; engtrans = 0.5 * masstotal * MathExtra::lensq3(vcm); // r12 = unit bond vector from atom1 to atom2 MathExtra::sub3(x[atom2],x[atom1],r12); MathExtra::norm3(r12); // delr = vector from COM to each atom // delv = velocity of each atom relative to COM MathExtra::sub3(x[atom1],xcm,delr1); MathExtra::sub3(x[atom2],xcm,delr2); MathExtra::sub3(v[atom1],vcm,delv1); MathExtra::sub3(v[atom2],vcm,delv2); // vpar = component of delv parallel to bond vector vpar1 = MathExtra::dot3(delv1,r12); vpar2 = MathExtra::dot3(delv2,r12); engvib = 0.5 * (mass1*vpar1*vpar1 + mass2*vpar2*vpar2); // vvib = relative velocity of 2 atoms along bond direction // vvib < 0 for 2 atoms moving towards each other // vvib > 0 for 2 atoms moving apart vvib = vpar2 - vpar1; // vrotsq = tangential speed squared of atom1 only // omegasq = omega squared, and is the same for atom1 and atom2 inertia = mass1*MathExtra::lensq3(delr1) + mass2*MathExtra::lensq3(delr2); vrotsq = MathExtra::lensq3(delv1) - vpar1*vpar1; omegasq = vrotsq / MathExtra::lensq3(delr1); engrot = 0.5 * inertia * omegasq; // sanity check: engtotal = engtrans + engvib + engrot //engtot = 0.5 * (mass1*MathExtra::lensq3(v[atom1]) + // mass2*MathExtra::lensq3(v[atom2])); //if (fabs(engtot-engtrans-engvib-engrot) > EPSILON) // error->one(FLERR,"Sanity check on 3 energy components failed"); // scale energies by units mvv2e = force->mvv2e; engtrans *= mvv2e; engvib *= mvv2e; engrot *= mvv2e; } if (nvalues == 1) ptr = &vector[m]; else ptr = array[m]; for (n = 0; n < nvalues; n++) { switch (bstyle[n]) { case DIST: ptr[n] = sqrt(rsq); break; case ENGPOT: ptr[n] = engpot; break; case FORCE: ptr[n] = sqrt(rsq)*fbond; break; case ENGVIB: ptr[n] = engvib; break; case ENGROT: ptr[n] = engrot; break; case ENGTRANS: ptr[n] = engtrans; break; case OMEGA: ptr[n] = sqrt(omegasq); break; case VELVIB: ptr[n] = vvib; break; } } } m++; } } return m; }
int ComputeBondLocal::compute_bonds(int flag) { int i,m,n,nb,atom1,atom2,imol,iatom,btype; tagint tagprev; double delx,dely,delz,rsq; double *ptr; double **x = atom->x; tagint *tag = atom->tag; int *num_bond = atom->num_bond; tagint **bond_atom = atom->bond_atom; int **bond_type = atom->bond_type; int *mask = atom->mask; int *molindex = atom->molindex; int *molatom = atom->molatom; Molecule **onemols = atom->avec->onemols; int nlocal = atom->nlocal; int newton_bond = force->newton_bond; int molecular = atom->molecular; Bond *bond = force->bond; double eng,fbond; m = n = 0; for (atom1 = 0; atom1 < nlocal; atom1++) { if (!(mask[atom1] & groupbit)) continue; if (molecular == 1) nb = num_bond[atom1]; else { if (molindex[atom1] < 0) continue; imol = molindex[atom1]; iatom = molatom[atom1]; nb = onemols[imol]->num_bond[iatom]; } for (i = 0; i < nb; i++) { if (molecular == 1) { btype = bond_type[atom1][i]; atom2 = atom->map(bond_atom[atom1][i]); } else { tagprev = tag[atom1] - iatom - 1; btype = atom->map(onemols[imol]->bond_type[iatom][i]); atom2 = atom->map(onemols[imol]->bond_atom[iatom][i]+tagprev); } if (atom2 < 0 || !(mask[atom2] & groupbit)) continue; if (newton_bond == 0 && tag[atom1] > tag[atom2]) continue; if (btype == 0) continue; if (flag) { delx = x[atom1][0] - x[atom2][0]; dely = x[atom1][1] - x[atom2][1]; delz = x[atom1][2] - x[atom2][2]; domain->minimum_image(delx,dely,delz); rsq = delx*delx + dely*dely + delz*delz; if (singleflag && (btype > 0)) eng = bond->single(btype,rsq,atom1,atom2,fbond); else eng = fbond = 0.0; if (nvalues == 1) ptr = &vector[m]; else ptr = array[m]; for (n = 0; n < nvalues; n++) { switch (bstyle[n]) { case DIST: ptr[n] = sqrt(rsq); break; case ENG: ptr[n] = eng; break; case FORCE: ptr[n] = sqrt(rsq)*fbond; break; } } } m++; } } return m; }