From 29a3844f11cb62d051271c57b782c2f9278db7cb Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Sat, 2 Jul 2011 09:27:11 +0200
Subject: [PATCH] Added possibility to enforce numerical derivatives

There is a new method for colvars and function, enforceNumericalDerivatives(),
which can be used in the constructor so as to enforce numerical derivatives.
It should be added to complex colvars for which we do not want to implement
numerical derivatives, or can be used at preliminary stage during CV
implementation.

I also added a check for colvar ENERGY, which cannot be done with
numerical derivatives
---
 src/ActionWithValue.cpp |  7 ++++++-
 src/ActionWithValue.h   | 16 ++++++++++++++--
 src/ColvarEnergy.cpp    |  1 +
 src/DumpDerivatives.cpp |  2 +-
 4 files changed, 22 insertions(+), 4 deletions(-)

diff --git a/src/ActionWithValue.cpp b/src/ActionWithValue.cpp
index 95f995b84..c0b289b39 100644
--- a/src/ActionWithValue.cpp
+++ b/src/ActionWithValue.cpp
@@ -4,7 +4,11 @@
 using namespace std;
 using namespace PLMD;
 
-
+void ActionWithValue::enforceNumericalDerivatives(){
+  numericalDerivatives=true;
+  log.printf("  WARNING: Numerical derivatives will be used\n");
+  log.printf("    (probably this object does not implement analytical derivatives yet)\n");
+}
 
 ActionWithValue::ActionWithValue(const ActionOptions&ao):
   Action(ao),
@@ -12,6 +16,7 @@ ActionWithValue::ActionWithValue(const ActionOptions&ao):
   numericalDerivatives(false)
 {
   parseFlag("NUMERICAL_DERIVATIVES",numericalDerivatives);
+  if(numericalDerivatives) log.printf("  using numerical derivatives\n");
 }
 
 ActionWithValue::~ActionWithValue(){
diff --git a/src/ActionWithValue.h b/src/ActionWithValue.h
index 2f5737e57..e24ca08b4 100644
--- a/src/ActionWithValue.h
+++ b/src/ActionWithValue.h
@@ -21,6 +21,13 @@ class ActionWithValue:
   void assertUnique(const std::string&name);
   int getValueIndex(const std::string&name)const;
   bool numericalDerivatives;
+protected:
+/// Enforce the use of numerical derivatives.
+/// This may be useful during the implementation of new collective
+/// variables. Before implementing the derivatives, the used can
+/// just tell plumed to use finite difference irrespectively of
+/// the NUMERICAL_DERIVATIVES keyword in the input file
+  void enforceNumericalDerivatives();
 public:
   ActionWithValue(const ActionOptions&ao);
   ~ActionWithValue();
@@ -61,6 +68,7 @@ public:
   void setValue(Value*,double);
 /// Set the default value (the one without name)
   void setValue(double);
+/// Check if numerical derivatives should be used
   bool checkNumericalDerivatives()const;
 };
 
@@ -75,7 +83,9 @@ void ActionWithValue::setValue(double d){
 }
 
 inline
-double ActionWithValue::getForce(int n){return values[n]->getForce();}
+double ActionWithValue::getForce(int n){
+  return values[n]->getForce();
+}
 
 inline
 void ActionWithValue::assertUnique(const std::string&name){
@@ -83,7 +93,9 @@ void ActionWithValue::assertUnique(const std::string&name){
 }
 
 inline
-int ActionWithValue::getNumberOfValues(){return values.size();}
+int ActionWithValue::getNumberOfValues(){
+  return values.size();
+}
 
 inline
 int ActionWithValue::getNumberOfParameters()const{
diff --git a/src/ColvarEnergy.cpp b/src/ColvarEnergy.cpp
index feeb6a059..1b700b061 100644
--- a/src/ColvarEnergy.cpp
+++ b/src/ColvarEnergy.cpp
@@ -40,6 +40,7 @@ ColvarEnergy::ColvarEnergy(const ActionOptions&ao):
 PLUMED_COLVAR_INIT(ao),
 components(false)
 {
+  assert(!checkNumericalDerivatives());
   std::vector<int> atoms;
   requestAtoms(atoms);
   isEnergy=true;
diff --git a/src/DumpDerivatives.cpp b/src/DumpDerivatives.cpp
index 2c1ed9c0a..8e1b55880 100644
--- a/src/DumpDerivatives.cpp
+++ b/src/DumpDerivatives.cpp
@@ -87,7 +87,7 @@ void DumpDerivatives::calculate(){
     fprintf(fp," %f",getTime());
     fprintf(fp," %u",ipar);
     for(unsigned i=0;i<getNumberOfArguments();i++){
-      fprintf(fp," %f",arguments[i]->getDerivatives()[ipar]);
+      fprintf(fp," %15.10f",arguments[i]->getDerivatives()[ipar]);
     };
     fprintf(fp,"\n");
   }
-- 
GitLab