LCOV - code coverage report
Current view: top level - colvar - Coordination.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 32 33 97.0 %
Date: 2025-12-04 11:19:34 Functions: 3 4 75.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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 "CoordinationBase.h"
      23             : #include "tools/SwitchingFunction.h"
      24             : #include "core/ActionRegister.h"
      25             : 
      26             : namespace PLMD {
      27             : namespace colvar {
      28             : 
      29             : //+PLUMEDOC COLVAR COORDINATION
      30             : /*
      31             : Calculate coordination numbers.
      32             : 
      33             : This keyword can be used to calculate the number of contacts between two groups of atoms
      34             : and is defined as
      35             : 
      36             : $$
      37             : \sum_{i\in A} \sum_{i\in B} s_{ij}
      38             : $$
      39             : 
      40             : where $s_{ij}$ is 1 if the contact between atoms $i$ and $j$ is formed and zero otherwise.
      41             : In actuality, $s_{ij}$ is replaced with a switching function so as to ensure that the calculated CV has continuous derivatives.
      42             : 
      43             : The default switching function is:
      44             : 
      45             : $$
      46             : s_{ij} = \frac{ 1 - \left(\frac{r_{ij}-d_0}{r_0}\right)^n } { 1 - \left(\frac{r_{ij}-d_0}{r_0}\right)^m }
      47             : $$
      48             : 
      49             : but it can be changed using the optional SWITCH option.  You can find more information about the various switching functions that you can
      50             : use with this action in the documentation for [LESS_THAN](LESS_THAN.md).
      51             : 
      52             : To make your __calculation faster you can use a neighbor list__, which makes it that only a relevant subset of the pairwise distance are calculated at every step.
      53             : 
      54             : If GROUPB is empty, the coordination  number will be calculated based on the $\frac{N(N-1)}{2}$ pairs in GROUPA. This avoids computing
      55             : permuted indexes (e.g. pair (i,j) and (j,i)) twice and ensures that the calculation runs at twice the speed.
      56             : 
      57             : Notice that if there are common atoms between GROUPA and GROUPB the switching function should be
      58             : equal to one. These "self contacts" are discarded by plumed (since version 2.1),
      59             : so that they actually count as "zero".
      60             : 
      61             : ## Examples
      62             : 
      63             : The following example instructs plumed to calculate the total coordination number of the atoms in group 1-10 with the atoms in group 20-100.  For atoms 1-10 coordination numbers are calculated that count the number of atoms from the second group that are within 0.3 nm of the central atom.  A neighbor list is used to make this calculation faster, this neighbor list is updated every 100 steps.
      64             : 
      65             : ```plumed
      66             : COORDINATION GROUPA=1-10 GROUPB=20-100 R_0=0.3 NLIST NL_CUTOFF=0.5 NL_STRIDE=100
      67             : ```
      68             : 
      69             : ```plumed
      70             : COORDINATION GROUPA=1-10 GROUPB=20-100 R_0=0.3 NLISTCELLS NL_CUTOFF=0.5 NL_STRIDE=80
      71             : ```
      72             : 
      73             : The following is a dummy example which should compute the value 0 because the self interaction
      74             : of atom 1 is skipped. Notice that in plumed 2.0 "self interactions" were not skipped, and the
      75             : same calculation should return 1.
      76             : 
      77             : ```plumed
      78             : c: COORDINATION GROUPA=1 GROUPB=1 R_0=0.3
      79             : PRINT ARG=c STRIDE=10
      80             : ````
      81             : 
      82             : Here's an example that shows what happens when COORDINATION is provided with
      83             : a single group:
      84             : 
      85             : ```plumed
      86             : # define some huge group:
      87             : group: GROUP ATOMS=1-1000
      88             : # Here's coordination of a group against itself:
      89             : c1: COORDINATION GROUPA=group GROUPB=group R_0=0.3
      90             : # Here's coordination within a single group:
      91             : x: COORDINATION GROUPA=group R_0=0.3
      92             : # This is just multiplying times 2 the variable x:
      93             : c2: COMBINE ARG=x COEFFICIENTS=2 PERIODIC=NO
      94             : 
      95             : # the two variables c1 and c2 should be identical, but the calculation of c2 is twice faster
      96             : # since it runs on half of the pairs.
      97             : PRINT ARG=c1,c2 STRIDE=10
      98             : ```
      99             : 
     100             : */
     101             : //+ENDPLUMEDOC
     102             : 
     103             : class Coordination : public CoordinationBase {
     104             :   SwitchingFunction switchingFunction;
     105             : 
     106             : public:
     107             :   explicit Coordination(const ActionOptions&);
     108             : // active methods:
     109             :   static void registerKeywords( Keywords& keys );
     110             :   double pairing(double distance,double&dfunc,unsigned i,unsigned j)const override;
     111             : };
     112             : 
     113             : PLUMED_REGISTER_ACTION(Coordination,"COORDINATION")
     114             : 
     115         227 : void Coordination::registerKeywords( Keywords& keys ) {
     116         227 :   CoordinationBase::registerKeywords(keys);
     117         227 :   keys.add("compulsory","NN","6","The n parameter of the switching function ");
     118         227 :   keys.add("compulsory","MM","0","The m parameter of the switching function; 0 implies 2*NN");
     119         227 :   keys.add("compulsory","D_0","0.0","The d_0 parameter of the switching function");
     120         227 :   keys.add("compulsory","R_0","The r_0 parameter of the switching function");
     121         227 :   keys.add("optional","SWITCH","This keyword is used if you want to employ an alternative to the continuous switching function defined above. "
     122             :            "The following provides information on the \\ref switchingfunction that are available. "
     123             :            "When this keyword is present you no longer need the NN, MM, D_0 and R_0 keywords.");
     124         454 :   keys.linkActionInDocs("SWITCH","LESS_THAN");
     125         454 :   keys.setValueDescription("scalar","the value of the coordination");
     126         227 : }
     127             : 
     128         225 : Coordination::Coordination(const ActionOptions&ao):
     129             :   Action(ao),
     130         225 :   CoordinationBase(ao) {
     131             : 
     132             :   std::string sw,errors;
     133         450 :   parse("SWITCH",sw);
     134         225 :   if(sw.length()>0) {
     135         176 :     switchingFunction.set(sw,errors);
     136         174 :     if( errors.length()!=0 ) {
     137           1 :       error("problem reading SWITCH keyword : " + errors );
     138             :     }
     139             :   } else {
     140          49 :     int nn=6;
     141          49 :     int mm=0;
     142          49 :     double d0=0.0;
     143          49 :     double r0=0.0;
     144          49 :     parse("R_0",r0);
     145          49 :     if(r0<=0.0) {
     146           0 :       error("R_0 should be explicitly specified and positive");
     147             :     }
     148          49 :     parse("D_0",d0);
     149          49 :     parse("NN",nn);
     150          47 :     parse("MM",mm);
     151          47 :     switchingFunction.set(nn,mm,r0,d0);
     152             :   }
     153             : 
     154         220 :   checkRead();
     155             : 
     156         445 :   log<<"  contacts are counted with cutoff "<<switchingFunction.description()<<"\n";
     157         235 : }
     158             : 
     159    16358386 : double Coordination::pairing(double distance,double&dfunc,unsigned i,unsigned j)const {
     160             :   (void) i; // avoid warnings
     161             :   (void) j; // avoid warnings
     162    16358386 :   return switchingFunction.calculateSqr(distance,dfunc);
     163             : }
     164             : 
     165             : }
     166             : 
     167             : }

Generated by: LCOV version 1.16