double InterMolecularTorsions::compute( const unsigned& tindex, multicolvar::AtomValuePack& myatoms ) const { Vector v1, v2, dv1, dv2, dconn, conn = getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) ); // Retrieve vectors std::vector<double> orient0( 5 ), orient1( 5 ); getInputData( 0, true, myatoms, orient0 ); getInputData( 1, true, myatoms, orient1 ); for(unsigned i=0; i<3; ++i) { v1[i]=orient0[2+i]; v2[i]=orient1[2+i]; } if( getBaseMultiColvar(0)->getNumberOfQuantities()<3 ) return 1.0; // Evaluate angle Torsion t; double angle = t.compute( v1, conn, v2, dv1, dconn, dv2 ); for(unsigned i=0; i<3; ++i) { orient0[i+2]=dv1[i]; orient1[i+2]=dv2[i]; } // And accumulate derivatives if( !doNotCalculateDerivatives() ) { MultiValue& myder0=getInputDerivatives( 0, true, myatoms ); mergeInputDerivatives( 1, 2, orient1.size(), 0, orient0, myder0, myatoms ); MultiValue& myder1=getInputDerivatives( 1, true, myatoms ); mergeInputDerivatives( 1, 2, orient0.size(), 1, orient1, myder1, myatoms ); addAtomDerivatives( 1, 0, -dconn, myatoms ); addAtomDerivatives( 1, 1, dconn, myatoms ); myatoms.addBoxDerivatives( 1, -extProduct( conn, dconn ) ); } return angle; }