int ReferenceLincsAlgorithm::apply( int numberOfAtoms, vector<RealVec>& atomCoordinates, vector<RealVec>& atomCoordinatesP, vector<RealOpenMM>& inverseMasses ){ // --------------------------------------------------------------------------------------- static const char* methodName = "\nReferenceLincsAlgorithm::apply"; static const RealOpenMM zero = 0.0; static const RealOpenMM one = 1.0; static const RealOpenMM two = 2.0; // --------------------------------------------------------------------------------------- if (_numberOfConstraints == 0) return SimTKOpenMMCommon::DefaultReturn; if( !_hasInitialized ) initialize(numberOfAtoms, inverseMasses); // Calculate the direction of each constraint, along with the initial RHS and solution vectors. for (int i = 0; i < _numberOfConstraints; i++) { int atom1 = _atomIndices[i][0]; int atom2 = _atomIndices[i][1]; _constraintDir[i] = RealVec(atomCoordinatesP[atom1][0]-atomCoordinatesP[atom2][0], atomCoordinatesP[atom1][1]-atomCoordinatesP[atom2][1], atomCoordinatesP[atom1][2]-atomCoordinatesP[atom2][2]); RealOpenMM invLength = (RealOpenMM)(1/SQRT((RealOpenMM)_constraintDir[i].dot(_constraintDir[i]))); _constraintDir[i][0] *= invLength; _constraintDir[i][1] *= invLength; _constraintDir[i][2] *= invLength; _rhs1[i] = _solution[i] = _sMatrix[i]*(one/invLength-_distance[i]); } // Build the coupling matrix. for (int c1 = 0; c1 < (int)_couplingMatrix.size(); c1++) { RealVec& dir1 = _constraintDir[c1]; for (int j = 0; j < (int)_couplingMatrix[c1].size(); j++) { int c2 = _linkedConstraints[c1][j]; RealVec& dir2 = _constraintDir[c2]; if (_atomIndices[c1][0] == _atomIndices[c2][0] || _atomIndices[c1][1] == _atomIndices[c2][1]) _couplingMatrix[c1][j] = (RealOpenMM)(-inverseMasses[_atomIndices[c1][0]]*_sMatrix[c1]*dir1.dot(dir2)*_sMatrix[c2]); else _couplingMatrix[c1][j] = (RealOpenMM)(inverseMasses[_atomIndices[c1][1]]*_sMatrix[c1]*dir1.dot(dir2)*_sMatrix[c2]); } } // Solve the matrix equation and update the positions. solveMatrix(); updateAtomPositions(numberOfAtoms, atomCoordinatesP, inverseMasses); // Correct for rotational lengthening. for (int i = 0; i < _numberOfConstraints; i++) { int atom1 = _atomIndices[i][0]; int atom2 = _atomIndices[i][1]; RealVec delta(atomCoordinatesP[atom1][0]-atomCoordinatesP[atom2][0], atomCoordinatesP[atom1][1]-atomCoordinatesP[atom2][1], atomCoordinatesP[atom1][2]-atomCoordinatesP[atom2][2]); RealOpenMM p2 = (RealOpenMM)(two*_distance[i]*_distance[i]-delta.dot(delta)); if (p2 < zero) p2 = zero; _rhs1[i] = _solution[i] = _sMatrix[i]*(_distance[i]-SQRT(p2)); } solveMatrix(); updateAtomPositions(numberOfAtoms, atomCoordinatesP, inverseMasses); return SimTKOpenMMCommon::DefaultReturn; }
MBPolReferenceDispersionForce::MBPolReferenceDispersionForce( ) : _nonbondedMethod(NoCutoff), _cutoff(1.0e+10) { _periodicBoxDimensions = RealVec( 0.0, 0.0, 0.0 ); }