Index: src/Dynamics/ForceAnnealing.hpp
===================================================================
--- src/Dynamics/ForceAnnealing.hpp	(revision 883d98e32486751ae22252eeb98f80d2325cf9c3)
+++ src/Dynamics/ForceAnnealing.hpp	(revision 8c0ac92693af2ed86924517e8854c32a9495d2b2)
@@ -17,4 +17,5 @@
 #include <functional>
 #include <iterator>
+#include <math.h>
 
 #include <boost/bind.hpp>
@@ -167,5 +168,5 @@
   {
     double stepwidth = 0.;
-    if (_GradientDifference.NormSquared() > MYEPSILON)
+    if (_GradientDifference.Norm() > MYEPSILON)
       stepwidth = fabs(_PositionDifference.ScalarProduct(_GradientDifference))/
           _GradientDifference.NormSquared();
@@ -200,6 +201,6 @@
         iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
       // atom's force vector gives steepest descent direction
-      const Vector currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
-      const Vector currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
+      const Vector &currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
+      const Vector &currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
       LOG(4, "DEBUG: currentPosition for atom #" << (*iter)->getId() << " is " << currentPosition);
       LOG(4, "DEBUG: currentGradient for atom #" << (*iter)->getId() << " is " << currentGradient);
@@ -248,8 +249,44 @@
   }
 
+  /** Performs Gradient optimization on a single atom using BarzilaiBorwein step width.
+   *
+   * \param _atom atom to anneal
+   * \param OldTimeStep old time step
+   * \param CurrentTimeStep current time step whose gradient we've just calculated
+   * \param TimeStepToSet time step to update (i.e. \f$ t + \Delta t \f$ in the sense of the velocity verlet)
+   */
+  void annealAtom_BarzilaiBorwein(
+      atom * const _atom,
+      const int &OldTimeStep,
+      const int &CurrentTimeStep,
+      const int &TimeStepToSet
+      )
+  {
+    // atom's force vector gives steepest descent direction
+    const Vector &oldPosition = _atom->getPositionAtStep(OldTimeStep);
+    const Vector &currentPosition = _atom->getPositionAtStep(CurrentTimeStep);
+    const Vector &oldGradient = _atom->getAtomicForceAtStep(OldTimeStep);
+    const Vector &currentGradient = _atom->getAtomicForceAtStep(CurrentTimeStep);
+    LOG(4, "DEBUG: oldPosition for atom #" << _atom->getId() << " is " << oldPosition);
+    LOG(4, "DEBUG: currentPosition for atom #" << _atom->getId() << " is " << currentPosition);
+    LOG(4, "DEBUG: oldGradient for atom #" << _atom->getId() << " is " << oldGradient);
+    LOG(4, "DEBUG: currentGradient for atom #" << _atom->getId() << " is " << currentGradient);
+//      LOG(4, "DEBUG: Force for atom #" << _atom->getId() << " is " << currentGradient);
+
+    // we use Barzilai-Borwein update with position reversed to get descent
+    const Vector PositionDifference = currentPosition - oldPosition;
+    const Vector GradientDifference = (currentGradient - oldGradient);
+    double stepwidth = getBarzilaiBorweinStepwidth(PositionDifference, GradientDifference);
+    Vector PositionUpdate = stepwidth * currentGradient;
+    LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
+
+    // finally set new values
+    _atom->setPositionAtStep(TimeStepToSet, currentPosition + PositionUpdate);
+  }
+
   /** Performs Gradient optimization on the atoms using BarzilaiBorwein step width.
    *
    * \note this can only be called when there are at least two optimization
-   * time steps present, i.e. this must be preceeded by a simple anneal().
+   * time steps present, i.e. this must be preceded by a simple anneal().
    *
    * We assume that forces have just been calculated.
@@ -274,28 +311,11 @@
     for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
         iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
-      // atom's force vector gives steepest descent direction
-      const Vector &oldPosition = (*iter)->getPositionAtStep(OldTimeStep);
-      const Vector &currentPosition = (*iter)->getPositionAtStep(CurrentTimeStep);
-      const Vector &oldGradient = (*iter)->getAtomicForceAtStep(OldTimeStep);
+
+      annealAtom_BarzilaiBorwein(*iter, OldTimeStep, CurrentTimeStep, _TimeStep);
+
+      // extract largest components for showing progress of annealing
       const Vector &currentGradient = (*iter)->getAtomicForceAtStep(CurrentTimeStep);
-      LOG(4, "DEBUG: oldPosition for atom #" << (*iter)->getId() << " is " << oldPosition);
-      LOG(4, "DEBUG: currentPosition for atom #" << (*iter)->getId() << " is " << currentPosition);
-      LOG(4, "DEBUG: oldGradient for atom #" << (*iter)->getId() << " is " << oldGradient);
-      LOG(4, "DEBUG: currentGradient for atom #" << (*iter)->getId() << " is " << currentGradient);
-//      LOG(4, "DEBUG: Force for atom #" << (*iter)->getId() << " is " << currentGradient);
-
-      // we use Barzilai-Borwein update with position reversed to get descent
-      const Vector PositionDifference = currentPosition - oldPosition;
-      const Vector GradientDifference = (currentGradient - oldGradient);
-      double stepwidth = getBarzilaiBorweinStepwidth(PositionDifference, GradientDifference);
-      Vector PositionUpdate = stepwidth * currentGradient;
-      LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
-
-      // extract largest components for showing progress of annealing
       for(size_t i=0;i<NDIM;++i)
         maxComponents[i] = std::max(maxComponents[i], fabs(currentGradient[i]));
-
-      // finally set new values
-      (*iter)->setPositionAtStep(_TimeStep, currentPosition + PositionUpdate);
     }
 
@@ -399,4 +419,5 @@
 
     std::map<atomId_t, Vector> GatheredUpdates; //!< gathers all updates which are applied at the end
+    std::map<atomId_t, double> LargestUpdate_per_Atom; //!< check whether updates cancelled each other
     for(typename AtomSetMixin<T>::iterator iter = AtomicForceManipulator<T>::atoms.begin();
         iter != AtomicForceManipulator<T>::atoms.end(); ++iter) {
@@ -428,4 +449,8 @@
       }
       Vector PositionUpdate = stepwidth * currentGradient;
+      // cap updates (if non-zero) at 0.2 angstroem. BB tends to overshoot.
+      for (size_t i=0;i<NDIM;++i)
+        if (fabs(PositionUpdate[i]) > MYEPSILON)
+          PositionUpdate[i] = std::min(0.5, fabs(PositionUpdate[i]))*PositionUpdate[i]/fabs(PositionUpdate[i]);
       LOG(3, "DEBUG: Update would be " << stepwidth << "*" << currentGradient << " = " << PositionUpdate);
 
@@ -558,5 +583,12 @@
         // hence, the decision is only based on sides once we have picked a side
         // depending on all bonds associated with have same good type.
-        const double sign = sides[first_per_side[sideno]];
+
+        // away from gradient (minus) and contracting
+        // or towards gradient (plus) and expanding
+        // gather all on same side and remove
+        const double sign =
+            (sides[first_per_side[sideno]] == types[first_per_side[sideno]])
+            ? sides[first_per_side[sideno]] : -1.*sides[first_per_side[sideno]];
+
         LOG(4, "DEBUG: Removing edges from side with sign " << sign);
         BondList::const_iterator bonditer = ListOfBonds.begin();
@@ -603,4 +635,6 @@
           if (GatheredUpdates.count((*setiter))) {
             GatheredUpdates[(*setiter)] += factor*PositionUpdate;
+            LargestUpdate_per_Atom[(*setiter)] =
+                std::max(LargestUpdate_per_Atom[(*setiter)], factor*PositionUpdate.Norm());
           } else {
             GatheredUpdates.insert(
@@ -608,4 +642,8 @@
                     (*setiter),
                     factor*PositionUpdate) );
+            LargestUpdate_per_Atom.insert(
+                std::make_pair(
+                    (*setiter),
+                    factor*PositionUpdate.Norm()) );
           }
         }
@@ -617,4 +655,8 @@
                 walker.getId(),
                 PositionUpdate) );
+        LargestUpdate_per_Atom.insert(
+            std::make_pair(
+                walker.getId(),
+                PositionUpdate.Norm()) );
       }
     }
@@ -624,5 +666,5 @@
       atom &walker = *(*iter);
       // extract largest components for showing progress of annealing
-      const Vector currentGradient = walker.getAtomicForceAtStep(CurrentTimeStep);
+      const Vector &currentGradient = walker.getAtomicForceAtStep(CurrentTimeStep);
       for(size_t i=0;i<NDIM;++i)
         maxComponents[i] = std::max(maxComponents[i], fabs(currentGradient[i]));
@@ -653,6 +695,17 @@
       for (size_t i=0;i<NDIM;++i)
         LargestUpdate[i] = std::max(LargestUpdate[i], fabs(update[i]));
-      walker->setPositionAtStep(_TimeStep,
-          walker->getPositionAtStep(CurrentTimeStep) + update); // - CommonTranslation);
+
+      std::map<atomId_t, double>::const_iterator largestiter = LargestUpdate_per_Atom.find(atomid);
+      ASSERT( largestiter != LargestUpdate_per_Atom.end(),
+          "ForceAnnealing() - walker with id "+toString(atomid)+" not in LargestUpdates.");
+      // if we had large updates but their sum is very small
+      if (update.Norm()/largestiter->second > MYEPSILON) {
+        walker->setPositionAtStep(_TimeStep,
+            walker->getPositionAtStep(CurrentTimeStep) + update); // - CommonTranslation);
+      } else {
+        // then recalc update with simple anneal
+        LOG(2, "WARNING: Updates on atom " << *iter << " cancel themselves, performing simple anneal step.");
+        annealAtom_BarzilaiBorwein(walker, OldTimeStep, CurrentTimeStep, _TimeStep);
+      }
     }
     LOG(1, "STATUS: Largest absolute update components are " << LargestUpdate);
