Index: src/Actions/FragmentationAction/FragmentationAutomationAction.cpp
===================================================================
--- src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision 666e9ebba7d8fba3763c06700f8a75ad1663b51d)
+++ src/Actions/FragmentationAction/FragmentationAutomationAction.cpp	(revision f0dea014c27138ca1226c3de4ae6a119610dfd7a)
@@ -114,4 +114,34 @@
 }
 
+template <class ResultClass>
+std::pair<double, double> getResiduals(const ResultClass &_result)
+{ return std::pair<double, double>(0.,0.); }
+
+std::pair<double, double> getResiduals(const MPQCData &_result)
+{ return std::make_pair(_result.accuracy, _result.desired_accuracy); }
+
+std::pair<double, double> getResiduals(const VMGData &_result)
+{ return std::make_pair(_result.relative_residual, _result.precision); }
+
+template <class ResultClass>
+bool checkResults(const typename std::map<JobId_t, ResultClass> &_results)
+{
+  bool result = true;
+  for (typename std::map<JobId_t, ResultClass>::const_iterator iter = _results.begin();
+      iter != _results.end(); ++iter) {
+    std::pair<double, double> residuals = getResiduals(iter->second);
+    if (residuals.second != 0.) {
+      if (residuals.first >= residuals.second) {
+        ELOG(1, "Fragment Job " << iter->first << " converged to " << residuals.first
+            << " instead of " << residuals.second);
+        result = false;
+      }
+    } else {
+      LOG(4, "DEBUG: Not checking accuracy because desired precision not given.");
+    }
+  }
+  return result;
+}
+
 ActionState::ptr FragmentationFragmentationAutomationAction::performCall() {
   boost::asio::io_service io_service;
@@ -165,6 +195,12 @@
 
     mpqccontroller.getResults(shortrangedata);
-    if (mpqccontroller.getExitflag() != 0)
-      return Action::failure;
+    if (!checkResults(shortrangedata)) {
+      ELOG(1, "At least one of the fragments' energy could not be properly minimized.");
+      return Action::failure;
+    }
+    if (mpqccontroller.getExitflag() != 0) {
+      ELOG(1, "MPQCCommandFragmentController returned non-zero exit flag.");
+      return Action::failure;
+    }
 
     Exitflag += mpqccontroller.getExitflag();
@@ -196,6 +232,8 @@
     mpqccontroller.run();
     stop();
-    if (mpqccontroller.getExitflag() != 0)
-      return Action::failure;
+    if (mpqccontroller.getExitflag() != 0) {
+      ELOG(1, "MPQCCommandFragmentController returned non-zero exit flag before getting results.");
+      return Action::failure;
+    }
 
     // get back the results and place them in shortrangedata
@@ -204,6 +242,12 @@
         "FragmentationFragmentationAutomationAction::performCall() - number of converted results "
         +toString(shortrangedata.size())+" and number of jobs "+toString(NumberJobs)+ " differ.");
-    if (mpqccontroller.getExitflag() != 0)
-      return Action::failure;
+    if (!checkResults(shortrangedata)) {
+      ELOG(1, "At least one of the fragments' energy could not be properly minimized.");
+      return Action::failure;
+    }
+    if (mpqccontroller.getExitflag() != 0) {
+      ELOG(1, "MPQCCommandFragmentController returned non-zero exit flag after getting results.");
+      return Action::failure;
+    }
 
     Exitflag += mpqccontroller.getExitflag();
@@ -245,6 +289,8 @@
     const size_t NoJobs = shortrangedata.size()+full_sample.size();
     vmgcontroller.requestIds(2*NoJobs);
-    if (vmgcontroller.getExitflag() != 0)
-      return Action::failure;
+    if (vmgcontroller.getExitflag() != 0) {
+      ELOG(1, "VMGFragmentController returned non-zero exit flag on requesting long-range ids.");
+      return Action::failure;
+    }
 
     // Phase Five a: create VMGJobs for electronic charge distribution
@@ -269,6 +315,8 @@
     // Phase Six a: calculate result
     vmgcontroller.waitforResults(NoJobs);
-    if (vmgcontroller.getExitflag() != 0)
-      return Action::failure;
+    if (vmgcontroller.getExitflag() != 0) {
+      ELOG(1, "VMGFragmentController returned non-zero exit flag before getting results.");
+      return Action::failure;
+    }
     vmgcontroller.getResults(longrangedata);
     ASSERT( NoJobs == longrangedata.size(),
@@ -276,4 +324,8 @@
         +toString(full_sample.size())+"="+toString(NoJobs)
         +" and first VMGresults "+toString(longrangedata.size())+" don't match.");
+    if (!checkResults(longrangedata)) {
+      ELOG(1, "At least one of the fragments' electronic long-range potential could not be properly minimized.");
+      return Action::failure;
+    }
     Exitflag += vmgcontroller.getExitflag();
 
@@ -308,6 +360,12 @@
           +toString(full_sample.size())+"="+toString(NoJobs)
           +" and second VMGresults "+toString(longrangedata_both.size())+" don't match.");
-      if (vmgcontroller.getExitflag() != 0)
+      if (!checkResults(longrangedata_both)) {
+        ELOG(1, "At least one of the fragments' nuclei long-range potential could not be properly minimized.");
         return Action::failure;
+      }
+      if (vmgcontroller.getExitflag() != 0) {
+        ELOG(1, "VMGFragmentController returned non-zero exit flag after getting results.");
+        return Action::failure;
+      }
       Exitflag += vmgcontroller.getExitflag();
 
