From 1f4b2ca1607552594e5b7781c7c795e9598d7609 Mon Sep 17 00:00:00 2001
From: Giovanni Bussi <giovanni.bussi@gmail.com>
Date: Tue, 10 Apr 2018 18:25:10 +0200
Subject: [PATCH] unique_ptr: analysis + gridtools

---
 src/analysis/Histogram.cpp        |  6 +++---
 src/gridtools/HistogramOnGrid.cpp | 16 +++++++++-------
 src/gridtools/HistogramOnGrid.h   |  2 +-
 3 files changed, 13 insertions(+), 11 deletions(-)

diff --git a/src/analysis/Histogram.cpp b/src/analysis/Histogram.cpp
index 564afb423..705e7f606 100644
--- a/src/analysis/Histogram.cpp
+++ b/src/analysis/Histogram.cpp
@@ -486,14 +486,14 @@ void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
     if( in_apply ) myvals.updateDynamicList();
   } else {
     plumed_assert( !in_apply );
-    std::vector<Value*> vv( myhist->getVectorOfValues() );
+    std::vector<std::unique_ptr<Value>> vv( myhist->getVectorOfValues() );
     std::vector<double> val( getNumberOfArguments() ), der( getNumberOfArguments() );
     // Retrieve the location of the grid point at which we are evaluating the kernel
     mygrid->getGridPointCoordinates( current, val );
     if( kernel ) {
       for(unsigned i=0; i<getNumberOfArguments(); ++i) vv[i]->set( val[i] );
       // Evaluate the histogram at the relevant grid point and set the values
-      double vvh = kernel->evaluate( vv, der,true); myvals.setValue( 1, vvh );
+      double vvh = kernel->evaluate( Tools::unique2raw(vv), der,true); myvals.setValue( 1, vvh );
     } else {
       plumed_merror("normalisation of vectors does not work with arguments and spherical grids");
       // Evalulate dot product
@@ -504,7 +504,7 @@ void Histogram::compute( const unsigned& current, MultiValue& myvals ) const {
       for(unsigned j=0; j<getNumberOfArguments(); ++j) der[j] *= (myhist->von_misses_concentration)*newval;
     }
     // Set the derivatives and delete the vector of values
-    for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); delete vv[i]; }
+    for(unsigned i=0; i<getNumberOfArguments(); ++i) { myvals.setDerivative( 1, i, der[i] ); }
   }
 }
 
diff --git a/src/gridtools/HistogramOnGrid.cpp b/src/gridtools/HistogramOnGrid.cpp
index 9195c6d2f..869b928d5 100644
--- a/src/gridtools/HistogramOnGrid.cpp
+++ b/src/gridtools/HistogramOnGrid.cpp
@@ -81,7 +81,10 @@ std::unique_ptr<KernelFunctions> HistogramOnGrid::getKernelAndNeighbors( std::ve
     neighbors[0] = getIndex( point ); return NULL;
   } else if( getType()=="flat" ) {
     std::unique_ptr<KernelFunctions> kernel(new KernelFunctions( point, bandwidths, kerneltype, "DIAGONAL", 1.0 ));
-    kernel->normalize( getVectorOfValues() ); getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors );
+// GB: Now values is destroyed when exiting this function.
+// I think before there was a leak
+    std::vector<std::unique_ptr<Value>> values=getVectorOfValues();
+    kernel->normalize( Tools::unique2raw(values) ); getNeighbors( kernel->getCenter(), nneigh, num_neigh, neighbors );
     return kernel;
   } else if( getType()=="fibonacci" ) {
     getNeighbors( point, nneigh, num_neigh, neighbors );
@@ -92,10 +95,10 @@ std::unique_ptr<KernelFunctions> HistogramOnGrid::getKernelAndNeighbors( std::ve
   return NULL;
 }
 
-std::vector<Value*> HistogramOnGrid::getVectorOfValues() const {
-  std::vector<Value*> vv;
+std::vector<std::unique_ptr<Value>> HistogramOnGrid::getVectorOfValues() const {
+  std::vector<std::unique_ptr<Value>> vv;
   for(unsigned i=0; i<dimension; ++i) {
-    vv.push_back(new Value());
+    vv.emplace_back(new Value());
     if( pbc[i] ) vv[i]->setDomain( str_min[i], str_max[i] );
     else vv[i]->setNotPeriodic();
   }
@@ -124,7 +127,7 @@ void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, st
     } else {
       double totwforce=0.0;
       std::vector<double> intforce( 2*dimension, 0.0 );
-      std::vector<Value*> vv( getVectorOfValues() );
+      std::vector<std::unique_ptr<Value>> vv( getVectorOfValues() );
 
       double newval; std::vector<unsigned> tindices( dimension ); std::vector<double> xx( dimension );
       for(unsigned i=0; i<num_neigh; ++i) {
@@ -133,7 +136,7 @@ void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, st
         getGridPointCoordinates( ineigh, tindices, xx );
         if( kernel ) {
           for(unsigned j=0; j<dimension; ++j) vv[j]->set(xx[j]);
-          newval = kernel->evaluate( vv, der, true );
+          newval = kernel->evaluate( Tools::unique2raw(vv), der, true );
         } else {
           // Evalulate dot product
           double dot=0; for(unsigned j=0; j<dimension; ++j) { dot+=xx[j]*point[j]; der[j]=xx[j]; }
@@ -169,7 +172,6 @@ void HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, st
           buffer[ bufstart + gridbuf + nder + 1 + kder ] += myvals.getDerivative( 0, kder );
         }
       }
-      for(unsigned i=0; i<dimension; ++i) delete vv[i];
     }
   }
 }
diff --git a/src/gridtools/HistogramOnGrid.h b/src/gridtools/HistogramOnGrid.h
index 5d28a6a73..c718e1929 100644
--- a/src/gridtools/HistogramOnGrid.h
+++ b/src/gridtools/HistogramOnGrid.h
@@ -53,7 +53,7 @@ public:
   virtual void accumulateForce( const unsigned& ipoint, const double& weight, const std::vector<double>& der, std::vector<double>& intforce ) const ;
   unsigned getNumberOfBufferPoints() const ;
   std::unique_ptr<KernelFunctions> getKernelAndNeighbors( std::vector<double>& point, unsigned& num_neigh, std::vector<unsigned>& neighbors ) const;
-  std::vector<Value*> getVectorOfValues() const ;
+  std::vector<std::unique_ptr<Value>> getVectorOfValues() const ;
   void addOneKernelEachTimeOnly() { addOneKernelAtATime=true; }
   virtual void getFinalForces( const std::vector<double>& buffer, std::vector<double>& finalForces );
   bool noDiscreteKernels() const ;
-- 
GitLab