Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 : Copyright (c) 2015-2023 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 "ActionWithInputMatrix.h" 23 : #include "multicolvar/AtomValuePack.h" 24 : #include "AdjacencyMatrixVessel.h" 25 : #include "AdjacencyMatrixBase.h" 26 : #include "core/ActionRegister.h" 27 : #include "core/PlumedMain.h" 28 : #include "core/ActionSet.h" 29 : 30 : //+PLUMEDOC MATRIXF ROWSUMS 31 : /* 32 : Sum the rows of a adjacency matrix. 33 : 34 : As discussed in the section of the manual on \ref contactmatrix a useful tool for developing complex collective variables is the notion of the 35 : so called adjacency matrix. An adjacency matrix is an \f$N \times N\f$ matrix in which the \f$i\f$th, \f$j\f$th element tells you whether 36 : or not the \f$i\f$th and \f$j\f$th atoms/molecules from a set of \f$N\f$ atoms/molecules are adjacent or not. This action allows you to calculate 37 : the sum of the rows in this adjacency matrix and to then calculate further functions of these quantities. 38 : 39 : \par Examples 40 : 41 : The first instruction in the following input file tells PLUMED to compute a \f$10 \times 10\f$ matrix in which the \f$ij\f$-element 42 : tells you whether atoms \f$i\f$ and \f$j\f$ are within 1.0 nm of each other. The numbers in each of this rows are then added together 43 : and the average value is computed. As such the following input provides an alternative method for calculating the coordination numbers 44 : of atoms 1 to 10. 45 : 46 : \plumedfile 47 : mat: CONTACT_MATRIX ATOMS=1-10 SWITCH={RATIONAL R_0=1.0} 48 : rsums: ROWSUMS MATRIX=mat MEAN 49 : PRINT ARG=rsums.* FILE=colvar 50 : \endplumedfile 51 : 52 : The following input demonstrates another way that an average coordination number can be computed. This input calculates the number of atoms 53 : with indices between 6 and 15 that are within the first coordination spheres of each of the atoms within indices between 1 and 5. The average 54 : coordination number is then calculated from these five coordination numbers and this quantity is output to a file. 55 : 56 : \plumedfile 57 : mat2: CONTACT_MATRIX ATOMSA=1-5 ATOMSB=6-15 SWITCH={RATIONAL R_0=1.0} 58 : rsums: ROWSUMS MATRIX=mat2 MEAN 59 : PRINT ARG=rsums.* FILE=colvar 60 : \endplumedfile 61 : 62 : */ 63 : //+ENDPLUMEDOC 64 : 65 : namespace PLMD { 66 : namespace adjmat { 67 : 68 : class MatrixRowSums : public ActionWithInputMatrix { 69 : public: 70 : static void registerKeywords( Keywords& keys ); 71 : explicit MatrixRowSums(const ActionOptions&); 72 : double compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const override; 73 : }; 74 : 75 10427 : PLUMED_REGISTER_ACTION(MatrixRowSums,"ROWSUMS") 76 : 77 5 : void MatrixRowSums::registerKeywords( Keywords& keys ) { 78 5 : ActionWithInputMatrix::registerKeywords( keys ); 79 15 : keys.use("ALT_MIN"); keys.use("LOWEST"); keys.use("HIGHEST"); 80 20 : keys.use("MEAN"); keys.use("MIN"); keys.use("MAX"); keys.use("LESS_THAN"); 81 20 : keys.use("MORE_THAN"); keys.use("BETWEEN"); keys.use("HISTOGRAM"); keys.use("MOMENTS"); 82 5 : } 83 : 84 4 : MatrixRowSums::MatrixRowSums(const ActionOptions& ao): 85 : Action(ao), 86 4 : ActionWithInputMatrix(ao) 87 : { 88 4 : if( (mymatrix->getMatrixAction())->mybasemulticolvars.size()>0 ) warning("matrix row may be problematic when inputs are not atoms"); 89 : // Setup the tasks 90 4 : unsigned nrows = mymatrix->getNumberOfRows(); 91 4 : ablocks.resize(1); ablocks[0].resize( nrows ); 92 147 : for(unsigned i=0; i<nrows; ++i) { ablocks[0][i]=i; addTaskToList( i ); } 93 4 : std::vector<AtomNumber> fake_atoms; setupMultiColvarBase( fake_atoms ); 94 4 : } 95 : 96 203 : double MatrixRowSums::compute( const unsigned& tinded, multicolvar::AtomValuePack& myatoms ) const { 97 203 : std::vector<double> tvals( mymatrix->getNumberOfComponents() ); 98 203 : getInputData( tinded, false, myatoms, tvals ); double fval=tvals[1]; 99 : 100 203 : if( !doNotCalculateDerivatives() ) { 101 75 : tvals.assign( tvals.size(), 0 ); tvals[1]=1.0; 102 75 : mergeInputDerivatives( 1, 1, 2, tinded, tvals, getInputDerivatives( tinded, false, myatoms ), myatoms ); 103 : } 104 203 : return fval; 105 : } 106 : 107 : } 108 : }