LCOV - code coverage report
Current view: top level - adjmat - AdjacencyMatrixVessel.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 71 78 91.0 %
Date: 2024-10-11 08:09:47 Functions: 14 15 93.3 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-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 "AdjacencyMatrixVessel.h"
      23             : #include "AdjacencyMatrixBase.h"
      24             : #include "vesselbase/ActionWithVessel.h"
      25             : 
      26             : namespace PLMD {
      27             : namespace adjmat {
      28             : 
      29          23 : void AdjacencyMatrixVessel::registerKeywords( Keywords& keys ) {
      30          23 :   StoreDataVessel::registerKeywords(keys);
      31          46 :   keys.addFlag("SYMMETRIC",false,"is the matrix symmetric");
      32          46 :   keys.addFlag("HBONDS",false,"can we think of the matrix as a undirected graph");
      33          23 : }
      34             : 
      35          23 : AdjacencyMatrixVessel::AdjacencyMatrixVessel( const vesselbase::VesselOptions& da ):
      36          23 :   StoreDataVessel(da)
      37             : {
      38          23 :   function=dynamic_cast<AdjacencyMatrixBase*>( getAction() );
      39          23 :   plumed_assert( function );
      40          46 :   parseFlag("SYMMETRIC",symmetric); parseFlag("HBONDS",hbonds);
      41          23 :   if( symmetric && hbonds ) error("matrix should be either symmetric or hbonds");
      42          23 :   if( symmetric && function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be symmetric but nrows!=ncols");
      43          23 :   if( hbonds &&  function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be hbonds but nrows!=ncols");
      44          23 : }
      45             : 
      46         775 : bool AdjacencyMatrixVessel::isSymmetric() const {
      47         775 :   return symmetric;
      48             : }
      49             : 
      50       72251 : bool AdjacencyMatrixVessel::undirectedGraph() const {
      51       72251 :   return ( symmetric || hbonds );
      52             : }
      53             : 
      54        1596 : unsigned AdjacencyMatrixVessel::getNumberOfRows() const {
      55        1596 :   return function->ablocks[0].size();
      56             : }
      57             : 
      58       39153 : unsigned AdjacencyMatrixVessel::getNumberOfColumns() const {
      59       39153 :   return function->ablocks[1].size();
      60             : }
      61             : 
      62       47892 : bool AdjacencyMatrixVessel::matrixElementIsActive( const unsigned& ielem, const unsigned& jelem ) const {
      63       47892 :   return StoreDataVessel::storedValueIsActive( getStoreIndexFromMatrixIndices( ielem, jelem ) );
      64             : }
      65             : 
      66       74692 : unsigned AdjacencyMatrixVessel::getStoreIndexFromMatrixIndices( const unsigned& ielem, const unsigned& jelem ) const {
      67       74692 :   if( !symmetric && !hbonds ) return (function->ablocks[1].size())*ielem + jelem;
      68       72692 :   if( !symmetric ) {
      69             :     plumed_dbg_assert( ielem!=jelem );
      70       32256 :     if( jelem<ielem ) return (function->ablocks[1].size()-1)*ielem + jelem;
      71       16128 :     return (function->ablocks[1].size()-1)*ielem + jelem - 1;
      72             :   }
      73       40436 :   if( ielem>jelem ) return 0.5*ielem*(ielem-1)+jelem;
      74       17363 :   return 0.5*jelem*(jelem-1) + ielem;
      75             : }
      76             : 
      77          17 : AdjacencyMatrixBase* AdjacencyMatrixVessel::getMatrixAction() {
      78          17 :   return function;
      79             : }
      80             : 
      81       24491 : void AdjacencyMatrixVessel::getMatrixIndices( const unsigned& code, unsigned& i, unsigned& j ) const {
      82       24491 :   std::vector<unsigned> myatoms; function->decodeIndexToAtoms( function->getTaskCode(code), myatoms );
      83       24491 :   i=myatoms[0]; j=myatoms[1];
      84       24491 :   if( !undirectedGraph() ) j -= function->ablocks[0].size(); // Have to remove number of columns as returns number in ablocks[1]
      85       24491 : }
      86             : 
      87          17 : void AdjacencyMatrixVessel::retrieveMatrix( DynamicList<unsigned>& myactive_elements, Matrix<double>& mymatrix ) {
      88          17 :   myactive_elements.deactivateAll(); std::vector<double> vals( getNumberOfComponents() );
      89        1564 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
      90        1547 :     retrieveSequentialValue( i, false, vals );
      91        1547 :     if( vals[0]<epsilon ) continue ;
      92             : 
      93        1547 :     myactive_elements.activate(i);
      94        1547 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
      95             : 
      96        1547 :     if( symmetric ) mymatrix(k,j)=mymatrix(j,k)=vals[0]*vals[1];
      97           0 :     else mymatrix(k,j)=vals[0]*vals[1];
      98             :   }
      99          17 :   myactive_elements.updateActiveMembers();
     100          17 : }
     101             : 
     102          24 : void AdjacencyMatrixVessel::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
     103             :   plumed_dbg_assert( undirectedGraph() );
     104             :   // Currently everything has zero neighbors
     105        8217 :   for(unsigned i=0; i<nneigh.size(); ++i) nneigh[i]=0;
     106             : 
     107             :   // And set up the adjacency list
     108          24 :   std::vector<double> myvals( getNumberOfComponents() );
     109      214258 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
     110             :     // Check if atoms are connected
     111      214234 :     retrieveSequentialValue( i, false, myvals );
     112      214234 :     if( myvals[0]<epsilon || myvals[1]<epsilon ) continue ;
     113             : 
     114       15013 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
     115             : 
     116       15013 :     if( nneigh[j]>=adj_list.ncols() || nneigh[k]>=adj_list.ncols() ) error("adjacency lists are not large enough, increase maxconnections");
     117             :     // Store if atoms are connected
     118             :     // unsigned j, k; getMatrixIndices( i, k, j );
     119       15013 :     adj_list(k,nneigh[k])=j; nneigh[k]++;
     120       15013 :     adj_list(j,nneigh[j])=k; nneigh[j]++;
     121             :   }
     122          24 : }
     123             : 
     124           4 : void AdjacencyMatrixVessel::retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& edge_list ) {
     125           4 :   plumed_dbg_assert( undirectedGraph() ); nedge=0;
     126           4 :   std::vector<double> myvals( getNumberOfComponents() );
     127           4 :   if( getNumberOfStoredValues()>edge_list.size() ) error("adjacency lists are not large enough, increase maxconnections");
     128             : 
     129      124576 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
     130             :     // Check if atoms are connected
     131      124572 :     retrieveSequentialValue( i, false, myvals );
     132      124572 :     if( myvals[0]<epsilon || myvals[1]<epsilon ) continue ;
     133             : 
     134        6384 :     getMatrixIndices( function->getPositionInFullTaskList(i), edge_list[nedge].first, edge_list[nedge].second );
     135        6384 :     nedge++;
     136             :   }
     137           4 : }
     138             : 
     139           0 : bool AdjacencyMatrixVessel::nodesAreConnected( const unsigned& iatom, const unsigned& jatom ) const {
     140           0 :   if( !matrixElementIsActive( iatom, jatom ) ) return false;
     141           0 :   unsigned ind=getStoreIndexFromMatrixIndices( iatom, jatom );
     142             : 
     143           0 :   std::vector<double> myvals( getNumberOfComponents() );
     144           0 :   retrieveValueWithIndex( ind, false, myvals );
     145           0 :   return ( myvals[0]>epsilon && myvals[1]>epsilon );
     146             : }
     147             : 
     148           8 : double AdjacencyMatrixVessel::getCutoffForConnection() const {
     149           8 :   return function->getLinkCellCutoff();
     150             : }
     151             : 
     152             : }
     153             : }
     154             : 

Generated by: LCOV version 1.15