From 08d8298428c9839f5dcaf050e6eb2950674179a0 Mon Sep 17 00:00:00 2001 From: Gareth Tribello <gareth.tribello@gmail.com> Date: Sat, 30 Jan 2016 12:22:17 +0000 Subject: [PATCH] Added first go at faster wcsurface stuff Now there is an option to update grids only in the region around where the contour was found in FindContour --- regtest/multicolvar/rt-wcsurface/plumed.dat | 9 ------ src/gridtools/ActionWithInputGrid.cpp | 6 ++++ src/gridtools/ActionWithInputGrid.h | 1 + src/gridtools/FindContour.cpp | 33 +++++++++++++++++++-- src/gridtools/GridVessel.cpp | 9 ++++-- src/gridtools/GridVessel.h | 22 ++++++++++---- src/gridtools/HistogramOnGrid.cpp | 1 + 7 files changed, 63 insertions(+), 18 deletions(-) delete mode 100644 regtest/multicolvar/rt-wcsurface/plumed.dat diff --git a/regtest/multicolvar/rt-wcsurface/plumed.dat b/regtest/multicolvar/rt-wcsurface/plumed.dat deleted file mode 100644 index 452ac0e42..000000000 --- a/regtest/multicolvar/rt-wcsurface/plumed.dat +++ /dev/null @@ -1,9 +0,0 @@ -UNITS NATURAL - -fcc: FCCUBIC SPECIES=1-5184 SWITCH={CUBIC D_0=1.2 D_MAX=1.5} ALPHA=27 - -DUMPMULTICOLVAR DATA=fcc ORIGIN=1 FILE=atoms.xyz PRECISION=4 -dens: MULTICOLVARDENS DATA=fcc ORIGIN=1 DIR=xyz NBINS=14,14,28 BANDWIDTH=1.0,1.0,1.0 - -PRINT_CUBE GRID=dens STRIDE=1 FILE=dens.cube -FIND_CONTOUR GRID=dens STRIDE=1 CONTOUR=0.42 FILE=surface.xyz PRECISION=4 diff --git a/src/gridtools/ActionWithInputGrid.cpp b/src/gridtools/ActionWithInputGrid.cpp index 7596d020b..88bc3ee69 100644 --- a/src/gridtools/ActionWithInputGrid.cpp +++ b/src/gridtools/ActionWithInputGrid.cpp @@ -78,6 +78,12 @@ void ActionWithInputGrid::setAnalysisStride( const bool& use_all, const unsigned void ActionWithInputGrid::update(){ if( unormalised ) norm = 1.0; else norm=1.0/mygrid->getNorm(); + + if( checkAllActive() ){ + for(unsigned i=0;i<mygrid->getNumberOfPoints();++i){ + if( mygrid->inactive(i) ) error("if FIND_CONTOUR is used with BUFFER option then other actions cannot be performed with grid"); + } + } performOperationsWithGrid( true ); } diff --git a/src/gridtools/ActionWithInputGrid.h b/src/gridtools/ActionWithInputGrid.h index 9b5251641..0246be6ae 100644 --- a/src/gridtools/ActionWithInputGrid.h +++ b/src/gridtools/ActionWithInputGrid.h @@ -47,6 +47,7 @@ public: void apply(){} void update(); void runFinalJobs(); + virtual bool checkAllActive() const { return true; } virtual void performOperationsWithGrid( const bool& from_update )=0; void setAnalysisStride( const bool& use_all, const unsigned& astride ); }; diff --git a/src/gridtools/FindContour.cpp b/src/gridtools/FindContour.cpp index 0a1c135ed..1ba4c7bce 100644 --- a/src/gridtools/FindContour.cpp +++ b/src/gridtools/FindContour.cpp @@ -33,6 +33,7 @@ class FindContour : public ActionWithInputGrid { private: OFile of; double lenunit; + unsigned gbuffer; std::string fmt_xyz; unsigned mycomp; double contour; @@ -40,6 +41,7 @@ private: public: static void registerKeywords( Keywords& keys ); explicit FindContour(const ActionOptions&ao); + bool checkAllActive() const { return gbuffer==0; } void performOperationsWithGrid( const bool& from_update ); double getDifferenceFromContour( const std::vector<double>& x, std::vector<double>& der ); unsigned getNumberOfDerivatives(){ return 0; } @@ -61,6 +63,7 @@ void FindContour::registerKeywords( Keywords& keys ){ "is thre dimensional specifying SEARCHDIR=1,2 means that only points found along grid lines parallel to the " "first and second axis of the grid will be looked for. The code will not search for the dividing surface " "along the third axis of the grid"); + keys.add("compulsory","BUFFER","0","number of buffer grid points around location where grid was found on last step. If this is zero the full grid is calculated on each step"); keys.add("optional","COMPONENT","if your input is a vector field use this to specifiy the component of the input vector field for which you wish to find the contour"); keys.add("optional", "PRECISION","The number of digits in trajectory file"); } @@ -79,8 +82,9 @@ nosearch_dirs( mygrid->getDimension() ) } if( mygrid->noDerivatives() ) error("cannot find contours if input grid has no derivatives"); - parse("CONTOUR",contour); + parse("CONTOUR",contour); parse("BUFFER",gbuffer); log.printf(" calculating dividing surface along which function equals %f \n", contour); + if( gbuffer>0 ) log.printf(" after first step a subset of only %d grid points around where the countour was found will be checked\n",gbuffer); std::string searchdir_str; parse("SEARCHDIR",searchdir_str); if( searchdir_str=="all" ){ @@ -149,10 +153,28 @@ void FindContour::performOperationsWithGrid( const bool& from_update ){ } // Run over whole grid + std::vector<bool> active( mygrid->getNumberOfPoints(), false ); + std::vector<unsigned> neighbours; unsigned num_neighbours; + std::vector<unsigned> gbuffer_vec( mygrid->getDimension(), gbuffer ); + std::vector<unsigned> ugrid_indices( mygrid->getDimension() ); unsigned npoints=0; RootFindingBase<FindContour> mymin( this ); for(unsigned i=0;i<mygrid->getNumberOfPoints();++i){ // Get the index of the current grid point mygrid->getIndices( i, ind ); + // Ensure inactive grid points are ignored + bool cycle=false; + if( mygrid->inactive(i) ) continue ; + for(unsigned j=0;j<mygrid->getDimension();++j) ugrid_indices[j]=ind[j]; + for(unsigned j=0;j<mygrid->getDimension();++j){ + if( mygrid->isPeriodic(j) ) ugrid_indices[j]=(ugrid_indices[j]+1)%nbin[j]; + else if( (ugrid_indices[j]+1)==nbin[j] ) continue ; + else ugrid_indices[j]+=1; + // Now check the grid is active + if( mygrid->inactive( mygrid->getIndex( ugrid_indices ) ) ){ cycle=true; break; } + // And reset ugrid_indices + ugrid_indices[j]=ind[j]; + } + if( cycle ) continue ; // Get the value of a point on the grid double val1=getGridElement( i, mycomp*(mygrid->getDimension()+1) ) - contour; @@ -173,13 +195,20 @@ void FindContour::performOperationsWithGrid( const bool& from_update ){ direction[j]=0.999999999*dx[j]; // And do proper search for contour point mymin.linesearch( direction, contour_points[npoints], &FindContour::getDifferenceFromContour ); - direction[j]=0.0; npoints++; + direction[j]=0.0; + // For next run through activate buffer region around this grid point + if( gbuffer>0 ){ + mygrid->getNeighbors( contour_points[npoints], gbuffer_vec, num_neighbours, neighbours ); + for(unsigned n=0;n<num_neighbours;++n) active[ neighbours[n] ]=true; + } + npoints++; } if( mygrid->isPeriodic(j) && edge ){ edge=false; ind[j]=nbin[j]-1; } else ind[j]-=1; } } + if( gbuffer>0 ) mygrid->activateThesePoints( active ); // Clear the grid ready for next time if( from_update ) mygrid->reset(); diff --git a/src/gridtools/GridVessel.cpp b/src/gridtools/GridVessel.cpp index 6c3b498b0..36b3e69a2 100644 --- a/src/gridtools/GridVessel.cpp +++ b/src/gridtools/GridVessel.cpp @@ -120,7 +120,7 @@ std::string GridVessel::description(){ void GridVessel::resize(){ plumed_massert( nper>0, "Number of datapoints at each grid point has not been set"); - resizeBuffer( npoints*nper ); data.resize( npoints*nper, 0 ); + resizeBuffer( npoints*nper ); data.resize( npoints*nper, 0 ); active.resize( npoints, true ); } unsigned GridVessel::getIndex( const std::vector<unsigned>& indices ) const { @@ -189,7 +189,7 @@ void GridVessel::getSplineNeighbors( const unsigned& mybox, std::vector<unsigned } double GridVessel::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const { - plumed_dbg_assert( bounds_set && ipoint<npoints && jelement<nper ); + plumed_assert( bounds_set && ipoint<npoints && jelement<nper && active[ipoint] ); return data[ nper*ipoint + jelement ]; } @@ -344,6 +344,11 @@ double GridVessel::getValueAndDerivatives( const std::vector<double>& x, const u return value; } +void GridVessel::activateThesePoints( const std::vector<bool>& to_activate ){ + plumed_dbg_assert( to_activate.size()==npoints ); + for(unsigned i=0;i<npoints;++i) active[i]=to_activate[i]; +} + } } diff --git a/src/gridtools/GridVessel.h b/src/gridtools/GridVessel.h index cdc74eac6..2e17bcbe4 100644 --- a/src/gridtools/GridVessel.h +++ b/src/gridtools/GridVessel.h @@ -50,8 +50,6 @@ private: std::vector<unsigned> stride; /// The number of bins in each grid direction std::vector<unsigned> nbin; -/// Flatten the grid and get the grid index for a point - unsigned getIndex( const std::vector<unsigned>& indices ) const ; /// The grid point that was requested last by getGridPointCoordinates unsigned currentGridPoint; protected: @@ -68,11 +66,10 @@ protected: std::vector<double> dx; /// The dimensionality of the grid unsigned dimension; +/// Which grid points are we actively accumulating + std::vector<bool> active; /// The grid with all the data values on it std::vector<double> data; -/// Get the set of points neighouring a particular location in space - void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh, - unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ; /// Get the indices of a particular point void getIndices( const std::vector<double>& point, std::vector<unsigned>& indices ) const ; /// Convert a point in space the the correspoinding grid point @@ -90,6 +87,8 @@ public: std::string description(); /// Convert an index into indices void convertIndexToIndices( const unsigned& index, const std::vector<unsigned>& nnbin, std::vector<unsigned>& indices ) const ; +/// Flatten the grid and get the grid index for a point + unsigned getIndex( const std::vector<unsigned>& indices ) const ; /// Get the indices fof a point void getIndices( const unsigned& index, std::vector<unsigned>& indices ) const ; @@ -127,6 +126,9 @@ public: double getCellVolume() const ; /// Get the value of the ith grid element double getGridElement( const unsigned&, const unsigned& ) const ; +/// Get the set of points neighouring a particular location in space + void getNeighbors( const std::vector<double>& pp, const std::vector<unsigned>& nneigh, + unsigned& num_neighbours, std::vector<unsigned>& neighbors ) const ; /// Get the points neighboring a particular spline point void getSplineNeighbors( const unsigned& mybox, std::vector<unsigned>& mysneigh ) const ; /// Get the spacing between grid points @@ -152,6 +154,10 @@ public: double getValueAndDerivatives( const std::vector<double>& x, const unsigned& ind, std::vector<double>& der ) const ; /// Was the grid cleared on the last step bool wasreset() const ; +/// Deactivate all the grid points + void activateThesePoints( const std::vector<bool>& to_activate ); +/// Is this point active + bool inactive( const unsigned& ip ) const ; }; inline @@ -216,6 +222,12 @@ bool GridVessel::wasreset() const { return wascleared; } +inline +bool GridVessel::inactive( const unsigned& ip ) const { + plumed_dbg_assert( ip<npoints ); + return !active[ip]; +} + } } #endif diff --git a/src/gridtools/HistogramOnGrid.cpp b/src/gridtools/HistogramOnGrid.cpp index edb89d003..a973ef906 100644 --- a/src/gridtools/HistogramOnGrid.cpp +++ b/src/gridtools/HistogramOnGrid.cpp @@ -85,6 +85,7 @@ bool HistogramOnGrid::calculate( const unsigned& current, MultiValue& myvals, st double newval; std::vector<double> der( dimension ); for(unsigned i=0;i<num_neigh;++i){ unsigned ineigh=neighbors[i]; + if( inactive( ineigh ) ) continue ; getGridPointCoordinates( ineigh, xx ); for(unsigned j=0;j<dimension;++j) vv[j]->set(xx[j]); newval = kernel.evaluate( vv, der, true ); -- GitLab