LCOV - code coverage report
Current view: top level - clusters - ClusteringBase.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 49 51 96.1 %
Date: 2026-11-05 10:19:04 Functions: 5 6 83.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2015-2020 The plumed team
       3             :    (see the PEOPLE file at the root of the distribution for a list of names)
       4             : 
       5             :    See http://www.plumed.org for more information.
       6             : 
       7             :    This file is part of plumed, version 2.
       8             : 
       9             :    plumed is free software: you can redistribute it and/or modify
      10             :    it under the terms of the GNU Lesser General Public License as published by
      11             :    the Free Software Foundation, either version 3 of the License, or
      12             :    (at your option) any later version.
      13             : 
      14             :    plumed is distributed in the hope that it will be useful,
      15             :    but WITHOUT ANY WARRANTY; without even the implied warranty of
      16             :    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      17             :    GNU Lesser General Public License for more details.
      18             : 
      19             :    You should have received a copy of the GNU Lesser General Public License
      20             :    along with plumed.  If not, see <http://www.gnu.org/licenses/>.
      21             : +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ */
      22             : #include "ClusteringBase.h"
      23             : #include "core/PlumedMain.h"
      24             : 
      25             : namespace PLMD {
      26             : namespace clusters {
      27             : 
      28          26 : void ClusteringBase::registerKeywords( Keywords& keys ) {
      29          26 :   matrixtools::MatrixOperationBase::registerKeywords( keys );
      30          26 :   keys.add("hidden","MASKED_INPUT_ALLOWED","turns on that you are allowed to use masked inputs ");
      31          52 :   keys.setValueDescription("vector","vector with length that is equal to the number of rows in the input matrix.  Elements of this vector are equal to the cluster that each node is a part of");
      32          26 :   keys.addDOI("10.1021/acs.jctc.6b01073");
      33          26 : }
      34             : 
      35          20 : ClusteringBase::ClusteringBase(const ActionOptions&ao):
      36             :   Action(ao),
      37             :   matrixtools::MatrixOperationBase(ao),
      38          20 :   number_of_cluster(-1) {
      39             :   // Do some checks on the input
      40          20 :   if( getPntrToArgument(0)->getShape()[0]!=getPntrToArgument(0)->getShape()[1] ) {
      41           0 :     error("input matrix should be square");
      42             :   }
      43             : 
      44             :   // Now create a value - this holds the data on which cluster each guy is in
      45          20 :   std::vector<std::size_t> shape(1);
      46          20 :   shape[0]=getPntrToArgument(0)->getShape()[0];
      47             :   // Build the store here to make sure that next action has all data
      48          20 :   addValue( shape );
      49          20 :   setNotPeriodic();
      50             :   // Resize local variables
      51          20 :   which_cluster.resize( getPntrToArgument(0)->getShape()[0] );
      52          20 :   cluster_sizes.resize( getPntrToArgument(0)->getShape()[0] );
      53          20 :   log<<"  Bibliography "<<plumed.cite("10.1021/acs.jctc.6b01073")<<"\n";
      54          20 : }
      55             : 
      56          47 : void ClusteringBase::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
      57             :   // Make sure we have the edges stored
      58          47 :   std::vector<std::pair<unsigned,unsigned> > pairs;
      59          47 :   std::vector<double> vals;
      60             :   unsigned nedge;
      61          47 :   getPntrToArgument(0)->retrieveEdgeList( nedge, pairs, vals );
      62             :   // Currently everything has zero neighbors
      63       21407 :   for(unsigned i=0; i<nneigh.size(); ++i) {
      64       21360 :     nneigh[i]=0;
      65             :   }
      66             :   // Resize the adjacency list if it is needed
      67          47 :   if( adj_list.ncols()!=getPntrToArgument(0)->getNumberOfColumns() ) {
      68          28 :     unsigned nrows = getPntrToArgument(0)->getShape()[0];
      69          28 :     adj_list.resize( nrows, getPntrToArgument(0)->getNumberOfColumns() );
      70             :   }
      71             : 
      72             :   // And set up the adjacency list
      73       66991 :   for(unsigned i=0; i<nedge; ++i) {
      74             :     // Store if atoms are connected
      75       66944 :     unsigned j=pairs[i].first, k=pairs[i].second;
      76       66944 :     if( j==k ) {
      77             :       continue;
      78             :     }
      79       66944 :     adj_list(j,nneigh[j])=k;
      80       66944 :     nneigh[j]++;
      81       66944 :     adj_list(k,nneigh[k])=j;
      82       66944 :     nneigh[k]++;
      83             :   }
      84          47 : }
      85             : 
      86          47 : void ClusteringBase::calculate() {
      87             :   // All the clusters have zero size initially
      88       21407 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) {
      89       21360 :     cluster_sizes[i].first=0;
      90       21360 :     cluster_sizes[i].second=i;
      91             :   }
      92             :   // Do the clustering bit
      93          47 :   performClustering();
      94             :   // Order the clusters in the system by size (this returns ascending order )
      95          47 :   std::sort( cluster_sizes.begin(), cluster_sizes.end() );
      96             :   // Set the elements of the value to the cluster identies
      97       21407 :   for(unsigned i=0; i<cluster_sizes.size(); ++i) {
      98       21360 :     double this_size = static_cast<double>(cluster_sizes.size()-i);
      99    21950732 :     for(unsigned j=0; j<cluster_sizes.size(); ++j) {
     100    21929372 :       if( which_cluster[j]==cluster_sizes[i].second ) {
     101       21360 :         getPntrToValue()->set( j, this_size );
     102             :       }
     103             :     }
     104             :   }
     105          47 : }
     106             : 
     107          47 : void ClusteringBase::apply() {
     108          47 :   if( getPntrToComponent(0)->forcesWereAdded() ) {
     109           0 :     error("forces on clustering actions cannot work as clustering is not differentiable");
     110             :   }
     111          47 : }
     112             : 
     113             : }
     114             : }

Generated by: LCOV version 1.16