diff --git a/src/adjmat/AdjacencyMatrixBase.cpp b/src/adjmat/AdjacencyMatrixBase.cpp
index 808725c6c796b4a2eef04d6fcc5074332e58f077..5af5c6751762e7960098fe6c8dbf46c03a562b4a 100644
--- a/src/adjmat/AdjacencyMatrixBase.cpp
+++ b/src/adjmat/AdjacencyMatrixBase.cpp
@@ -204,19 +204,6 @@ void AdjacencyMatrixBase::requestAtoms( const std::vector<AtomNumber>& atoms, co
   setupMultiColvarBase( atoms );
 }
 
-void AdjacencyMatrixBase::addAtomDerivatives( const unsigned& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const {
-  unsigned jatom=myatoms.getIndex(iatom);
-
-  if( jatom>colvar_label.size() ){
-      myatoms.addAtomsDerivatives( ival, jatom, der );
-  } else {
-      unsigned mmc=colvar_label[jatom];
-      unsigned basen=0; for(unsigned i=0;i<mmc;++i) basen+=mybasemulticolvars[i]->getNumberOfAtoms();
-      multicolvar::CatomPack atom0=mybasemulticolvars[mmc]->getCentralAtomPack( basen, convertToLocalIndex(jatom,mmc) );
-      myatoms.addComDerivatives( ival, der, atom0 );
-  }
-}
-
 // Maybe put this back GAT to check that it is returning an atom number that is one of the nodes
 // and not a hydrogen if we are doing HBPAMM
 // AtomNumber AdjacencyMatrixBase::getAbsoluteIndexOfCentralAtom(const unsigned& i) const {
diff --git a/src/adjmat/AdjacencyMatrixBase.h b/src/adjmat/AdjacencyMatrixBase.h
index 8db15e752cdb7accd5501692462880b022f1eafd..4ff1a1d44a2936fa73541599258ef2319adcea53 100644
--- a/src/adjmat/AdjacencyMatrixBase.h
+++ b/src/adjmat/AdjacencyMatrixBase.h
@@ -66,8 +66,6 @@ protected:
   void requestAtoms( const std::vector<AtomNumber>& atoms, const bool& symmetric, const unsigned& nrows );
 /// Return the group this atom is a part of
   unsigned getBaseColvarNumber( const unsigned& ) const ;
-/// Add some derivatives to a particular component of a particular atom
-  void addAtomDerivatives( const unsigned& , const unsigned& , const Vector& , multicolvar::AtomValuePack& ) const ;
 /// Add some derivatives to the relevant orientation
   void addOrientationDerivatives( const unsigned&, const unsigned& , const std::vector<double>& , multicolvar::AtomValuePack& ) const ;
 public:
diff --git a/src/crystallization/Fccubic.cpp b/src/crystallization/Fccubic.cpp
index 617ae7070bda514c1be1907ac83b991e9c036acd..47b95a6dadcc0d5ff1a6d0267dfd2b9cf2f58b1e 100644
--- a/src/crystallization/Fccubic.cpp
+++ b/src/crystallization/Fccubic.cpp
@@ -197,11 +197,11 @@ double Fccubic::compute( const unsigned& tindex, multicolvar::AtomValuePack& mya
   
          fder = (+dfunc)*tmp*distance + sw*myder;
 
-         myatoms.addAtomsDerivatives( 1, 0, -fder );
-         myatoms.addAtomsDerivatives( 1, i, +fder );
+         addAtomDerivatives( 1, 0, -fder, myatoms );
+         addAtomDerivatives( 1, i, +fder, myatoms);
          myatoms.addBoxDerivatives( 1, Tensor(distance,-fder) );
-         myatoms.addAtomsDerivatives( 0, 0, (-dfunc)*distance );
-         myatoms.addAtomsDerivatives( 0, i, (+dfunc)*distance );
+         addAtomDerivatives( 0, 0, (-dfunc)*distance, myatoms);
+         addAtomDerivatives( 0, i, (+dfunc)*distance, myatoms);
          myatoms.addBoxDerivatives( 0, (-dfunc)*Tensor(distance,distance) );
       }
    }
diff --git a/src/crystallization/MoleculeOrientation.cpp b/src/crystallization/MoleculeOrientation.cpp
index ef892889762ebda83dd02fca3cb2fc9ccbb77886..4a7879ce4e2b61a88d72c7b9d8d3f17e904da641 100644
--- a/src/crystallization/MoleculeOrientation.cpp
+++ b/src/crystallization/MoleculeOrientation.cpp
@@ -89,18 +89,18 @@ VectorMultiColvar(ao)
 void MoleculeOrientation::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
   Vector distance; distance=getSeparation( myatoms.getPosition(0), myatoms.getPosition(1) );
 
-  myatoms.addAtomsDerivatives( 2, 0, Vector(-1.0,0,0) ); 
-  myatoms.addAtomsDerivatives( 2, 1, Vector(+1.0,0,0) ); 
+  addAtomDerivatives( 2, 0, Vector(-1.0,0,0), myatoms ); 
+  addAtomDerivatives( 2, 1, Vector(+1.0,0,0), myatoms ); 
   myatoms.addBoxDerivatives( 2, Tensor(distance,Vector(-1.0,0,0)) ); 
   myatoms.addValue( 2, distance[0] ); 
 
-  myatoms.addAtomsDerivatives( 3, 0, Vector(0,-1.0,0) ); 
-  myatoms.addAtomsDerivatives( 3, 1, Vector(0,+1.0,0) ); 
+  addAtomDerivatives( 3, 0, Vector(0,-1.0,0), myatoms ); 
+  addAtomDerivatives( 3, 1, Vector(0,+1.0,0), myatoms ); 
   myatoms.addBoxDerivatives( 3, Tensor(distance,Vector(0,-1.0,0)) ); 
   myatoms.addValue( 3, distance[1] ); 
 
-  myatoms.addAtomsDerivatives( 4, 0, Vector(0,0,-1.0) ); 
-  myatoms.addAtomsDerivatives( 4, 1, Vector(0,0,+1.0) ); 
+  addAtomDerivatives( 4, 0, Vector(0,0,-1.0), myatoms ); 
+  addAtomDerivatives( 4, 1, Vector(0,0,+1.0), myatoms ); 
   myatoms.addBoxDerivatives( 4, Tensor(distance,Vector(0,0,-1.0)) ); 
   myatoms.addValue( 4, distance[2] ); 
 }
diff --git a/src/crystallization/MoleculePlane.cpp b/src/crystallization/MoleculePlane.cpp
index ae259d325cb2763bce9a0ebb210b7ffc6db4d54b..cb4f953dcc25c2dfe467bbc1257c02d050e1f0c4 100644
--- a/src/crystallization/MoleculePlane.cpp
+++ b/src/crystallization/MoleculePlane.cpp
@@ -81,38 +81,38 @@ void MoleculePlane::calculateVector( multicolvar::AtomValuePack& myatoms ) const
   }
   cp = crossProduct( d1, d2 );
 
-  myatoms.addAtomsDerivatives( 2, 0, crossProduct( Vector(-1.0,0,0), d2 ) );
+  addAtomDerivatives( 2, 0, crossProduct( Vector(-1.0,0,0), d2 ), myatoms );
   if( myatoms.getNumberOfAtoms()==3 ){
-     myatoms.addAtomsDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ) + crossProduct( Vector(-1.0,0,0), d1 ) );
-     myatoms.addAtomsDerivatives( 2, 2, crossProduct( Vector(+1.0,0,0), d1 ) );
+     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ) + crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+     addAtomDerivatives( 2, 2, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
   } else {
-     myatoms.addAtomsDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ) ); 
-     myatoms.addAtomsDerivatives( 2, 2, crossProduct( Vector(-1.0,0,0), d1 ) );
-     myatoms.addAtomsDerivatives( 2, 3, crossProduct( Vector(+1.0,0,0), d1 ) );
+     addAtomDerivatives( 2, 1, crossProduct( Vector(+1.0,0,0), d2 ), myatoms ); 
+     addAtomDerivatives( 2, 2, crossProduct( Vector(-1.0,0,0), d1 ), myatoms );
+     addAtomDerivatives( 2, 3, crossProduct( Vector(+1.0,0,0), d1 ), myatoms );
   }
   myatoms.addBoxDerivatives( 2, Tensor(d1,crossProduct(Vector(+1.0,0,0), d2)) + Tensor( d2, crossProduct(Vector(-1.0,0,0), d1)) );
   myatoms.addValue( 2, cp[0] );
 
-  myatoms.addAtomsDerivatives( 3, 0, crossProduct( Vector(0,-1.0,0), d2 ) );
+  addAtomDerivatives( 3, 0, crossProduct( Vector(0,-1.0,0), d2 ), myatoms );
   if( myatoms.getNumberOfAtoms()==3 ){
-     myatoms.addAtomsDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ) + crossProduct( Vector(0,-1.0,0), d1 ) );
-     myatoms.addAtomsDerivatives( 3, 2, crossProduct( Vector(0,+1.0,0), d1 ) );
+     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ) + crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     addAtomDerivatives( 3, 2, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
   } else {
-     myatoms.addAtomsDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ) ); 
-     myatoms.addAtomsDerivatives( 3, 2, crossProduct( Vector(0,-1.0,0), d1 ) );
-     myatoms.addAtomsDerivatives( 3, 3, crossProduct( Vector(0,+1.0,0), d1 ) );
+     addAtomDerivatives( 3, 1, crossProduct( Vector(0,+1.0,0), d2 ), myatoms ); 
+     addAtomDerivatives( 3, 2, crossProduct( Vector(0,-1.0,0), d1 ), myatoms );
+     addAtomDerivatives( 3, 3, crossProduct( Vector(0,+1.0,0), d1 ), myatoms );
   }
   myatoms.addBoxDerivatives( 3, Tensor(d1,crossProduct(Vector(0,+1.0,0), d2)) + Tensor( d2, crossProduct(Vector(0,-1.0,0), d1)) );
   myatoms.addValue( 3, cp[1] );
 
-  myatoms.addAtomsDerivatives( 4, 0, crossProduct( Vector(0,0,-1.0), d2 ) );
+  addAtomDerivatives( 4, 0, crossProduct( Vector(0,0,-1.0), d2 ), myatoms );
   if( myatoms.getNumberOfAtoms()==3 ){
-     myatoms.addAtomsDerivatives( 4, 1, crossProduct( Vector(0,0,+1.0), d2 ) + crossProduct( Vector(0,0,-1.0), d1 ) );
-     myatoms.addAtomsDerivatives( 4, 2, crossProduct( Vector(0,0,+1.0), d1 ) );
+     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,+1.0), d2 ) + crossProduct( Vector(0,0,-1.0), d1 ), myatoms );
+     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
   } else {
-     myatoms.addAtomsDerivatives( 4, 1, crossProduct( Vector(0,0,-1.0), d2 ) ); 
-     myatoms.addAtomsDerivatives( 4, 2, crossProduct( Vector(0,0,-1.0), d1 ) );
-     myatoms.addAtomsDerivatives( 4, 3, crossProduct( Vector(0,0,+1.0), d1 ) );
+     addAtomDerivatives( 4, 1, crossProduct( Vector(0,0,-1.0), d2 ), myatoms); 
+     addAtomDerivatives( 4, 2, crossProduct( Vector(0,0,-1.0), d1 ), myatoms);
+     addAtomDerivatives( 4, 3, crossProduct( Vector(0,0,+1.0), d1 ), myatoms);
   }
   myatoms.addBoxDerivatives( 4, Tensor(d1,crossProduct(Vector(0,0,+1.0), d2)) + Tensor( d2, crossProduct(Vector(0,0,-1.0), d1)) );
   myatoms.addValue( 4, cp[2] );
diff --git a/src/crystallization/OrientationSphere.cpp b/src/crystallization/OrientationSphere.cpp
index 319de6dcb5871939d0224fa8e0398f4513b1b510..2ea92618c5b755049fbe5ce8352338433a0b8eb2 100644
--- a/src/crystallization/OrientationSphere.cpp
+++ b/src/crystallization/OrientationSphere.cpp
@@ -108,13 +108,12 @@ double OrientationSphere::compute( const unsigned& tindex, multicolvar::AtomValu
              mergeVectorDerivatives( 1, 2, this_orient.size(), myatoms.getIndex(0), this_orient, myder0, myatoms );  
              mergeVectorDerivatives( 1, 2, catom_der.size(), myatoms.getIndex(i), catom_der, myder1, myatoms );
              myatoms.addComDerivatives( 1, f_dot*(-dfunc)*distance, atom0 );
-             multicolvar::CatomPack atom1=getCentralAtomPackFromInput( myatoms.getIndex(i) );
-             myatoms.addComDerivatives( 1, f_dot*(dfunc)*distance, atom1 );
+             addAtomDerivatives( 1, i, f_dot*(dfunc)*distance, myatoms );
              myatoms.addBoxDerivatives( 1, (-dfunc)*f_dot*Tensor(distance,distance) );
              myder1.clearAll();
               
              myatoms.addComDerivatives( 0, (-dfunc)*distance, atom0 );
-             myatoms.addComDerivatives( 0, (dfunc)*distance, atom1  );
+             addAtomDerivatives( 0, i, (dfunc)*distance, myatoms );
              myatoms.addBoxDerivatives( 0, (-dfunc)*Tensor(distance,distance) );
 
          }
diff --git a/src/crystallization/SimpleCubic.cpp b/src/crystallization/SimpleCubic.cpp
index 3bb23d476da60cc10636d0b8f2d0bdadeb0ffe06..4165bf0b53aba129005d624fc35746820a1a378d 100644
--- a/src/crystallization/SimpleCubic.cpp
+++ b/src/crystallization/SimpleCubic.cpp
@@ -148,14 +148,14 @@ double SimpleCubic::compute( const unsigned& tindex, multicolvar::AtomValuePack&
          myder[2] = 4*z3/t2-4*distance[2]*t3; 
 
          value += sw*tmp; fder = (+dfunc)*tmp*distance + sw*myder;
-         myatoms.addAtomsDerivatives( 1, 0, -fder );
-         myatoms.addAtomsDerivatives( 1, i, +fder );
+         addAtomDerivatives( 1, 0, -fder, myatoms );
+         addAtomDerivatives( 1, i, +fder, myatoms );
          // Tens is a constructor that you build by taking the vector product of two vectors (remember the scalars!)
          myatoms.addBoxDerivatives( 1, Tensor(distance,-fder) );
  
          norm += sw;
-         myatoms.addAtomsDerivatives( 0, 0, (-dfunc)*distance );
-         myatoms.addAtomsDerivatives( 0, i, (+dfunc)*distance );
+         addAtomDerivatives( 0, 0, (-dfunc)*distance, myatoms );
+         addAtomDerivatives( 0, i, (+dfunc)*distance, myatoms );
          myatoms.addBoxDerivatives( 0, (-dfunc)*Tensor(distance,distance) );
       }
    }
diff --git a/src/crystallization/Steinhardt.cpp b/src/crystallization/Steinhardt.cpp
index 3ce6c8be6d60991e018c3b1ec878f1e575ccf666..6041e0dd6597722552b4a8bd00462d181ac20e9d 100644
--- a/src/crystallization/Steinhardt.cpp
+++ b/src/crystallization/Steinhardt.cpp
@@ -86,8 +86,8 @@ void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
          double dlen3 = d2*dlen;
 
          // Store derivatives of weight
-         myatoms.addAtomsDerivatives( 1, 0, (-dfunc)*distance );
-         myatoms.addAtomsDerivatives( 1, i, (+dfunc)*distance );
+         addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
+         addAtomDerivatives( 1, i, (+dfunc)*distance, myatoms );
          myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor( distance,distance ) ); 
 
          // Do stuff for m=0
@@ -97,8 +97,8 @@ void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
          // Derivative wrt to the vector connecting the two atoms
          myrealvec = (+sw)*dpoly_ass*dz + poly_ass*(+dfunc)*distance;
          // Accumulate the derivatives
-         myatoms.addAtomsDerivatives( 2 + tmom, 0, -myrealvec );      
-         myatoms.addAtomsDerivatives( 2 + tmom, i, myrealvec ); 
+         addAtomDerivatives( 2 + tmom, 0, -myrealvec, myatoms );      
+         addAtomDerivatives( 2 + tmom, i, myrealvec, myatoms); 
          myatoms.addBoxDerivatives( 2 + tmom, Tensor( -myrealvec,distance ) );
          // And store the vector function
          myatoms.addValue( 2 + tmom, sw*poly_ass );
@@ -134,13 +134,13 @@ void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
 
              // Real part
              myatoms.addValue( 2+tmom+m, sw*tq6 );
-             myatoms.addAtomsDerivatives( 2+tmom+m, 0, -myrealvec );
-             myatoms.addAtomsDerivatives( 2+tmom+m, i, myrealvec );
+             addAtomDerivatives( 2+tmom+m, 0, -myrealvec, myatoms );
+             addAtomDerivatives( 2+tmom+m, i, myrealvec, myatoms );
              myatoms.addBoxDerivatives( 2+tmom+m, Tensor( -myrealvec,distance ) );
              // Imaginary part 
              myatoms.addValue( 2+ncomp+tmom+m, sw*itq6 );
-             myatoms.addAtomsDerivatives( 2+ncomp+tmom+m, 0, -myimagvec );
-             myatoms.addAtomsDerivatives( 2+ncomp+tmom+m, i, myimagvec );
+             addAtomDerivatives( 2+ncomp+tmom+m, 0, -myimagvec, myatoms );
+             addAtomDerivatives( 2+ncomp+tmom+m, i, myimagvec, myatoms );
              myatoms.addBoxDerivatives( 2+ncomp+tmom+m, Tensor( -myimagvec,distance ) );
              // Store -m part of vector
              double pref=pow(-1.0,m); 
@@ -148,13 +148,13 @@ void Steinhardt::calculateVector( multicolvar::AtomValuePack& myatoms ) const {
              // conjugate of Legendre polynomial
              // Real part
              myatoms.addValue( 2+tmom-m, pref*sw*tq6 );
-             myatoms.addAtomsDerivatives( 2+tmom-m, 0, -pref*myrealvec );
-             myatoms.addAtomsDerivatives( 2+tmom-m, i, pref*myrealvec );
+             addAtomDerivatives( 2+tmom-m, 0, -pref*myrealvec, myatoms );
+             addAtomDerivatives( 2+tmom-m, i, pref*myrealvec, myatoms );
              myatoms.addBoxDerivatives( 2+tmom-m, pref*Tensor( -myrealvec,distance ) );
              // Imaginary part
              myatoms.addValue( 2+ncomp+tmom-m, -pref*sw*itq6 );
-             myatoms.addAtomsDerivatives( 2+ncomp+tmom-m, 0, pref*myimagvec );
-             myatoms.addAtomsDerivatives( 2+ncomp+tmom-m, i, -pref*myimagvec );
+             addAtomDerivatives( 2+ncomp+tmom-m, 0, pref*myimagvec, myatoms );
+             addAtomDerivatives( 2+ncomp+tmom-m, i, -pref*myimagvec, myatoms );
              myatoms.addBoxDerivatives( 2+ncomp+tmom-m, pref*Tensor( myimagvec,distance ) );
          }
      }
diff --git a/src/crystallization/Tetrahedral.cpp b/src/crystallization/Tetrahedral.cpp
index cb1f09d4084cb98dd87bd7cc22eacadbaed81043..a70da37acd24b240202172626c6de0616ae74e77 100644
--- a/src/crystallization/Tetrahedral.cpp
+++ b/src/crystallization/Tetrahedral.cpp
@@ -174,14 +174,14 @@ double Tetrahedral::compute( const unsigned& tindex, multicolvar::AtomValuePack&
          myder[2] = (tt1-(distance[2]*t1))  + (-tt2-(distance[2]*t2))  + (-tt3-(distance[2]*t3))  + (tt4-(distance[2]*t4));
 
          value += sw*tmp; fder = (+dfunc)*tmp*distance + sw*myder;
-         myatoms.addAtomsDerivatives( 1, 0, -fder );
-         myatoms.addAtomsDerivatives( 1, i, +fder );
+         addAtomDerivatives( 1, 0, -fder, myatoms );
+         addAtomDerivatives( 1, i, +fder, myatoms );
          // Tens is a constructor that you build by taking the vector product of two vectors (remember the scalars!)
          myatoms.addBoxDerivatives( 1, Tensor(distance,-fder) );
  
          norm += sw;
-         myatoms.addAtomsDerivatives( 0, 0, (-dfunc)*distance );
-         myatoms.addAtomsDerivatives( 0, i, (+dfunc)*distance );
+         addAtomDerivatives( 0, 0, (-dfunc)*distance, myatoms );
+         addAtomDerivatives( 0, i, (+dfunc)*distance, myatoms );
          myatoms.addBoxDerivatives( 0, (-dfunc)*Tensor(distance,distance) );
       }
    }
diff --git a/src/multicolvar/AlphaBeta.cpp b/src/multicolvar/AlphaBeta.cpp
index 307a3b26e2b4dd6e4ca4cd6eeafc8f52c0e4ec3c..0005d6951fb96ced13491ad7200531b945fd01a8 100644
--- a/src/multicolvar/AlphaBeta.cpp
+++ b/src/multicolvar/AlphaBeta.cpp
@@ -165,10 +165,10 @@ double AlphaBeta::compute( const unsigned& tindex, AtomValuePack& myatoms ) cons
   dd2 *= svalue;
   value = 0.5*cvalue;
 
-  myatoms.addAtomsDerivatives(1, 0,dd0);
-  myatoms.addAtomsDerivatives(1, 1,dd1-dd0);
-  myatoms.addAtomsDerivatives(1, 2,dd2-dd1);
-  myatoms.addAtomsDerivatives(1, 3,-dd2);
+  addAtomDerivatives(1, 0,dd0,myatoms);
+  addAtomDerivatives(1, 1,dd1-dd0,myatoms);
+  addAtomDerivatives(1, 2,dd2-dd1,myatoms);
+  addAtomDerivatives(1, 3,-dd2,myatoms);
 
   myatoms.addBoxDerivatives(1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
 
diff --git a/src/multicolvar/Angles.cpp b/src/multicolvar/Angles.cpp
index cf108fd5e92e85de7f31a999f64f436d483c79d0..714dfade11f2077e63bbe71b9f7e005f97d698cc 100644
--- a/src/multicolvar/Angles.cpp
+++ b/src/multicolvar/Angles.cpp
@@ -185,9 +185,9 @@ void Angles::calculateWeight( AtomValuePack& myatoms ) const {
   wtot=w1*w2; dw1*=w2; dw2*=w1; 
 
   myatoms.setValue( 0, wtot );
-  myatoms.addAtomsDerivatives( 0, 1, dw2*dik );
-  myatoms.addAtomsDerivatives( 0, 0, -dw1*dij - dw2*dik ); 
-  myatoms.addAtomsDerivatives( 0, 2, dw1*dij );
+  addAtomDerivatives( 0, 1, dw2*dik, myatoms );
+  addAtomDerivatives( 0, 0, -dw1*dij - dw2*dik, myatoms ); 
+  addAtomDerivatives( 0, 2, dw1*dij, myatoms );
   myatoms.addBoxDerivatives( 0, (-dw1)*Tensor(dij,dij) + (-dw2)*Tensor(dik,dik) );
 }
 
@@ -199,9 +199,9 @@ double Angles::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
   double angle=a.compute(dij,dik,ddij,ddik);
 
   // And finish the calculation
-  myatoms.addAtomsDerivatives( 1, 1, ddik );
-  myatoms.addAtomsDerivatives( 1, 0, - ddik - ddij );
-  myatoms.addAtomsDerivatives( 1, 2, ddij );
+  addAtomDerivatives( 1, 1, ddik, myatoms );
+  addAtomDerivatives( 1, 0, - ddik - ddij, myatoms );
+  addAtomDerivatives( 1, 2, ddij, myatoms );
   myatoms.addBoxDerivatives( 1, -(Tensor(dij,ddij)+Tensor(dik,ddik)) );
 
   return angle;
diff --git a/src/multicolvar/AtomValuePack.h b/src/multicolvar/AtomValuePack.h
index ce2a81daac46d48c3b880e27e8fe2d6b4188a28e..be587009acdf2ef8b389eb19f10ac0c9a0534aae 100644
--- a/src/multicolvar/AtomValuePack.h
+++ b/src/multicolvar/AtomValuePack.h
@@ -34,6 +34,8 @@ namespace multicolvar {
 class CatomPack;
 
 class AtomValuePack {
+friend class MultiColvarBase;
+friend class LocalAverage;
 private:
 /// Copy of the values that we are adding to
   MultiValue& myvals;
@@ -47,6 +49,10 @@ private:
   std::vector<unsigned>& sort_vector;
 /// This holds atom positions
   std::vector<Vector>& myatoms;
+///
+  void addDerivative( const unsigned& , const unsigned& , const double& );
+///
+  void addAtomsDerivatives( const unsigned& , const unsigned& , const Vector& );
 public:
   AtomValuePack( MultiValue& vals, MultiColvarBase const * mcolv );
 /// Set the number of atoms
@@ -71,10 +77,6 @@ public:
   void addValue( const unsigned& ival, const double& vv );
 ///
   double getValue( const unsigned& ) const ;
-///
-  void addDerivative( const unsigned& , const unsigned& , const double& );
-///
-  void addAtomsDerivatives( const unsigned& , const unsigned& , const Vector& );
 ///
   void addBoxDerivatives( const unsigned& , const Tensor& );
 ///
diff --git a/src/multicolvar/Bridge.cpp b/src/multicolvar/Bridge.cpp
index e8352e31a08c37fcd69f4d83b84e962558ce24e0..11911b6fecb68c7722c93aacd64faafde5a3abf0 100644
--- a/src/multicolvar/Bridge.cpp
+++ b/src/multicolvar/Bridge.cpp
@@ -144,8 +144,8 @@ void Bridge::calculateWeight( AtomValuePack& myatoms ) const {
   double dw, w=sf2.calculateSqr( ldij, dw );
   myatoms.setValue( 0, w );
 
-  myatoms.addAtomsDerivatives( 0, 0, -dw*dij );
-  myatoms.addAtomsDerivatives( 0, 2, dw*dij );
+  addAtomDerivatives( 0, 0, -dw*dij, myatoms );
+  addAtomDerivatives( 0, 2, dw*dij, myatoms );
   myatoms.addBoxDerivatives( 0, (-dw)*Tensor(dij,dij) );
 }
 
@@ -154,8 +154,8 @@ double Bridge::compute( const unsigned& tindex, AtomValuePack& myatoms ) const {
   double dw, w=sf1.calculateSqr( dik.modulo2(), dw );
 
   // And finish the calculation
-  myatoms.addAtomsDerivatives( 1, 0, -dw*dik );
-  myatoms.addAtomsDerivatives( 1, 1,  dw*dik );
+  addAtomDerivatives( 1, 0, -dw*dik, myatoms );
+  addAtomDerivatives( 1, 1,  dw*dik, myatoms );
   myatoms.addBoxDerivatives( 1, (-dw)*Tensor(dik,dik) );
   return w;
 }
diff --git a/src/multicolvar/CoordinationNumbers.cpp b/src/multicolvar/CoordinationNumbers.cpp
index ae618b6d5e357649b3a09240921d07a4f7e2005f..fae71b1c13a45c2b372f4575afb7cb0794f483c0 100644
--- a/src/multicolvar/CoordinationNumbers.cpp
+++ b/src/multicolvar/CoordinationNumbers.cpp
@@ -134,8 +134,8 @@ double CoordinationNumbers::compute( const unsigned& tindex, AtomValuePack& myat
          sw = switchingFunction.calculateSqr( d2, dfunc );
   
          value += sw;             
-         myatoms.addAtomsDerivatives( 1, 0, (-dfunc)*distance );
-         myatoms.addAtomsDerivatives( 1, i,  (dfunc)*distance );
+         addAtomDerivatives( 1, 0, (-dfunc)*distance, myatoms );
+         addAtomDerivatives( 1, i,  (dfunc)*distance, myatoms );
          myatoms.addBoxDerivatives( 1, (-dfunc)*Tensor(distance,distance) );
       }
    }
diff --git a/src/multicolvar/DihedralCorrelation.cpp b/src/multicolvar/DihedralCorrelation.cpp
index f5d1b7aa42a336ec7f64e7a0f96ef5697c9fdb16..5134aadfc70a8637fc0bdb554945d778b84f4dd7 100644
--- a/src/multicolvar/DihedralCorrelation.cpp
+++ b/src/multicolvar/DihedralCorrelation.cpp
@@ -141,20 +141,20 @@ double DihedralCorrelation::compute( const unsigned& tindex, AtomValuePack& myat
   dd11 *= 0.5*sin( phi2 - phi1 );
   dd12 *= 0.5*sin( phi2 - phi1 );
   // And add
-  myatoms.addAtomsDerivatives(1, 0, dd10);
-  myatoms.addAtomsDerivatives(1, 1, dd11-dd10);
-  myatoms.addAtomsDerivatives(1, 2, dd12-dd11);
-  myatoms.addAtomsDerivatives(1, 3, -dd12);
+  addAtomDerivatives(1, 0, dd10, myatoms );
+  addAtomDerivatives(1, 1, dd11-dd10, myatoms );
+  addAtomDerivatives(1, 2, dd12-dd11, myatoms );
+  addAtomDerivatives(1, 3, -dd12, myatoms );
   myatoms.addBoxDerivatives  (1, -(extProduct(d10,dd10)+extProduct(d11,dd11)+extProduct(d12,dd12)));
   // Derivative wrt phi2
   dd20 *= -0.5*sin( phi2 - phi1 );
   dd21 *= -0.5*sin( phi2 - phi1 );
   dd22 *= -0.5*sin( phi2 - phi1 );
   // And add
-  myatoms.addAtomsDerivatives(1, 4, dd20);
-  myatoms.addAtomsDerivatives(1, 5, dd21-dd20);
-  myatoms.addAtomsDerivatives(1, 6, dd22-dd21);
-  myatoms.addAtomsDerivatives(1, 7, -dd22);
+  addAtomDerivatives(1, 4, dd20, myatoms );
+  addAtomDerivatives(1, 5, dd21-dd20, myatoms );
+  addAtomDerivatives(1, 6, dd22-dd21, myatoms );
+  addAtomDerivatives(1, 7, -dd22, myatoms );
   myatoms.addBoxDerivatives(1, -(extProduct(d20,dd20)+extProduct(d21,dd21)+extProduct(d22,dd22)));
 
   return value;
diff --git a/src/multicolvar/Distances.cpp b/src/multicolvar/Distances.cpp
index 2bf9839d9b2cfaedfba90139f13ea6c6b636859d..83bc7e8f364759b761f6360afdf7c8c50042da3a 100644
--- a/src/multicolvar/Distances.cpp
+++ b/src/multicolvar/Distances.cpp
@@ -191,8 +191,8 @@ double Distances::compute( const unsigned& tindex, AtomValuePack& myatoms ) cons
    const double invvalue=1.0/value;
 
    // And finish the calculation
-   myatoms.addAtomsDerivatives( 1, 0,-invvalue*distance );
-   myatoms.addAtomsDerivatives( 1, 1, invvalue*distance );
+   addAtomDerivatives( 1, 0,-invvalue*distance, myatoms );
+   addAtomDerivatives( 1, 1, invvalue*distance, myatoms );
    myatoms.addBoxDerivatives( 1, -invvalue*Tensor(distance,distance) );
    return value;
 }
diff --git a/src/multicolvar/InPlaneDistances.cpp b/src/multicolvar/InPlaneDistances.cpp
index 0fb720ea0eb1250fec427f3a6e1bb33daf1c1f65..1b59ac7d875abb594a9f0aa252c61282d085de8d 100644
--- a/src/multicolvar/InPlaneDistances.cpp
+++ b/src/multicolvar/InPlaneDistances.cpp
@@ -115,9 +115,9 @@ double InPlaneDistances::compute( const unsigned& tindex, AtomValuePack& myatoms
   double sangle=sin(angle), cangle=cos(angle); 
   double dd=dir.modulo(), invdd=1.0/dd, val=dd*sangle;
 
-  myatoms.addAtomsDerivatives( 1, 0, dd*cangle*ddik + sangle*invdd*dir );
-  myatoms.addAtomsDerivatives( 1, 1, -dd*cangle*(ddik+ddij) - sangle*invdd*dir );
-  myatoms.addAtomsDerivatives( 1, 2, dd*cangle*ddij );
+  addAtomDerivatives( 1, 0, dd*cangle*ddik + sangle*invdd*dir, myatoms );
+  addAtomDerivatives( 1, 1, -dd*cangle*(ddik+ddij) - sangle*invdd*dir, myatoms );
+  addAtomDerivatives( 1, 2, dd*cangle*ddij, myatoms );
   myatoms.addBoxDerivatives( 1, -dd*cangle*(Tensor(normal,ddij)+Tensor(dir,ddik)) - sangle*invdd*Tensor(dir,dir) );
 
   return val;
diff --git a/src/multicolvar/MultiColvarBase.cpp b/src/multicolvar/MultiColvarBase.cpp
index 63bdf985bff7b1b24dba5786b82ae5f7051141a7..39eb6039c3fb656353bfb2b4e534f9de1d9b56b1 100644
--- a/src/multicolvar/MultiColvarBase.cpp
+++ b/src/multicolvar/MultiColvarBase.cpp
@@ -388,6 +388,19 @@ void MultiColvarBase::calculate(){
   runAllTasks();
 }
 
+void MultiColvarBase::addAtomDerivatives( const unsigned& ival, const unsigned& iatom, const Vector& der, multicolvar::AtomValuePack& myatoms ) const {
+  unsigned jatom=myatoms.getIndex(iatom);
+
+  if( jatom<colvar_label.size() ){
+      unsigned mmc=colvar_label[jatom];
+      unsigned basen=0; for(unsigned i=0;i<mmc;++i) basen+=mybasemulticolvars[i]->getNumberOfAtoms();
+      multicolvar::CatomPack atom0=mybasemulticolvars[mmc]->getCentralAtomPack( basen, convertToLocalIndex(jatom,mmc) );
+      myatoms.addComDerivatives( ival, der, atom0 );
+  } else {
+      myatoms.addAtomsDerivatives( ival, iatom, der );
+  }
+}
+
 void MultiColvarBase::performTask( const unsigned& task_index, const unsigned& current, MultiValue& myvals ) const {
 
   AtomValuePack myatoms( myvals, this );
diff --git a/src/multicolvar/MultiColvarBase.h b/src/multicolvar/MultiColvarBase.h
index fd3c5268ce4ee49b651ca788ae088c3d37d22da1..0958b74d4b35501b8c5aabe1343ed741fef8d3d8 100644
--- a/src/multicolvar/MultiColvarBase.h
+++ b/src/multicolvar/MultiColvarBase.h
@@ -87,6 +87,8 @@ protected:
   void addTaskToList( const unsigned& taskCode );
 /// Finish setting up the multicolvar base
   void setupMultiColvarBase( const std::vector<AtomNumber>& atoms );
+/// Add some derivatives to a particular component of a particular atom
+  void addAtomDerivatives( const unsigned& , const unsigned& , const Vector& , multicolvar::AtomValuePack& ) const ;
 /// Set which atoms are to be used to calculate the central atom position
   void setAtomsForCentralAtom( const std::vector<bool>& catom_ind );
 /// Set the value of the cutoff for the link cells
@@ -179,7 +181,7 @@ Vector MultiColvarBase::getPositionOfAtomForLinkCells( const unsigned& iatom ) c
       return mybasemulticolvars[mmc]->getCentralAtomPos( convertToLocalIndex(iatom,mmc) );
   }
   return ActionAtomistic::getPosition( iatom );
-} 
+}
 
 inline
 unsigned MultiColvarBase::getNumberOfDerivatives(){
diff --git a/src/multicolvar/NumberOfLinks.cpp b/src/multicolvar/NumberOfLinks.cpp
index a810206ce72af816720cb98a7293f75ed6394951..011cf185909dc67dfe8589cd0ad3f3d367db1319 100644
--- a/src/multicolvar/NumberOfLinks.cpp
+++ b/src/multicolvar/NumberOfLinks.cpp
@@ -136,10 +136,8 @@ void NumberOfLinks::calculateWeight( AtomValuePack& myatoms ) const {
   myatoms.setValue(0,sw);
 
   if( !doNotCalculateDerivatives() ){
-      CatomPack atom0=getCentralAtomPackFromInput( myatoms.getIndex(0) );
-      myatoms.addComDerivatives( 0, (-dfunc)*distance, atom0 );
-      CatomPack atom1=getCentralAtomPackFromInput( myatoms.getIndex(1) );
-      myatoms.addComDerivatives( 0, (dfunc)*distance, atom1 );
+      addAtomDerivatives( 0, 0, (-dfunc)*distance, myatoms );
+      addAtomDerivatives( 0, 1, (dfunc)*distance, myatoms );
       myatoms.addBoxDerivatives( 0, (-dfunc)*Tensor(distance,distance) ); 
   }
 }
diff --git a/src/multicolvar/Torsions.cpp b/src/multicolvar/Torsions.cpp
index 235a34283ba15eb65bd4d24d2adafb4040f69b26..93864c264a0f5b8206a96a89744bed9c0d99b41f 100644
--- a/src/multicolvar/Torsions.cpp
+++ b/src/multicolvar/Torsions.cpp
@@ -110,10 +110,10 @@ double Torsions::compute( const unsigned& tindex, AtomValuePack& myatoms ) const
   Vector dd0,dd1,dd2; PLMD::Torsion t;
   double value  = t.compute(d0,d1,d2,dd0,dd1,dd2);
 
-  myatoms.addAtomsDerivatives(1,0,dd0);
-  myatoms.addAtomsDerivatives(1,1,dd1-dd0);
-  myatoms.addAtomsDerivatives(1,2,dd2-dd1);
-  myatoms.addAtomsDerivatives(1,3,-dd2);
+  addAtomDerivatives(1,0,dd0,myatoms);
+  addAtomDerivatives(1,1,dd1-dd0,myatoms);
+  addAtomDerivatives(1,2,dd2-dd1,myatoms);
+  addAtomDerivatives(1,3,-dd2,myatoms);
 
   myatoms.addBoxDerivatives  (1, -(extProduct(d0,dd0)+extProduct(d1,dd1)+extProduct(d2,dd2)));
 
diff --git a/src/multicolvar/XDistances.cpp b/src/multicolvar/XDistances.cpp
index 0333cf952a7b3694f29d3daec68ad7a7e4b06d1c..e34859880c2a1e3eea0badfec3cedea4dfc02e3e 100644
--- a/src/multicolvar/XDistances.cpp
+++ b/src/multicolvar/XDistances.cpp
@@ -158,8 +158,8 @@ double XDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) con
 
    Vector myvec; myvec.zero(); 
    // And finish the calculation
-   myvec[myc]=+1; myatoms.addAtomsDerivatives( 1, 1, myvec  );
-   myvec[myc]=-1; myatoms.addAtomsDerivatives( 1, 0, myvec );
+   myvec[myc]=+1; addAtomDerivatives( 1, 1, myvec, myatoms );
+   myvec[myc]=-1; addAtomDerivatives( 1, 0, myvec, myatoms );
    myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
    return value;
 }
diff --git a/src/multicolvar/XYDistances.cpp b/src/multicolvar/XYDistances.cpp
index 9836c0d105aeb9908fb66861f1383b7938ecd3d2..2919b39c2a2b3fd6cd635467b9cd70be73d4b995 100644
--- a/src/multicolvar/XYDistances.cpp
+++ b/src/multicolvar/XYDistances.cpp
@@ -136,8 +136,8 @@ double XYDistances::compute( const unsigned& tindex, AtomValuePack& myatoms ) co
 
    Vector myvec; myvec.zero(); 
    // And finish the calculation
-   myvec[myc1]=+invvalue*distance[myc1]; myvec[myc2]=+invvalue*distance[myc2]; myatoms.addAtomsDerivatives( 1, 1, myvec  );
-   myvec[myc1]=-invvalue*distance[myc1]; myvec[myc2]=-invvalue*distance[myc2]; myatoms.addAtomsDerivatives( 1, 0, myvec );
+   myvec[myc1]=+invvalue*distance[myc1]; myvec[myc2]=+invvalue*distance[myc2]; addAtomDerivatives( 1, 1, myvec, myatoms  );
+   myvec[myc1]=-invvalue*distance[myc1]; myvec[myc2]=-invvalue*distance[myc2]; addAtomDerivatives( 1, 0, myvec, myatoms );
    myatoms.addBoxDerivatives( 1, Tensor(distance,myvec) );
    return value;
 }