LCOV - code coverage report
Current view: top level - adjmat - AdjacencyMatrixVessel.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 69 94 73.4 %
Date: 2018-12-19 07:49:13 Functions: 17 19 89.5 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-2018 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          15 : void AdjacencyMatrixVessel::registerKeywords( Keywords& keys ) {
      30          15 :   StoreDataVessel::registerKeywords(keys);
      31          15 :   keys.addFlag("SYMMETRIC",false,"is the matrix symmetric");
      32          15 :   keys.addFlag("HBONDS",false,"can we think of the matrix as a undirected graph");
      33          15 : }
      34             : 
      35          15 : AdjacencyMatrixVessel::AdjacencyMatrixVessel( const vesselbase::VesselOptions& da ):
      36          15 :   StoreDataVessel(da)
      37             : {
      38          15 :   function=dynamic_cast<AdjacencyMatrixBase*>( getAction() );
      39          15 :   plumed_assert( function );
      40          15 :   parseFlag("SYMMETRIC",symmetric); parseFlag("HBONDS",hbonds);
      41          15 :   if( symmetric && hbonds ) error("matrix should be either symmetric or hbonds");
      42          15 :   if( symmetric && function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be symmetric but nrows!=ncols");
      43          15 :   if( hbonds &&  function->ablocks[0].size()!=function->ablocks[1].size() ) error("matrix is supposed to be hbonds but nrows!=ncols");
      44          15 : }
      45             : 
      46         751 : bool AdjacencyMatrixVessel::isSymmetric() const {
      47         751 :   return symmetric;
      48             : }
      49             : 
      50       22180 : bool AdjacencyMatrixVessel::undirectedGraph() const {
      51       22180 :   return ( symmetric || hbonds );
      52             : }
      53             : 
      54         177 : unsigned AdjacencyMatrixVessel::getNumberOfRows() const {
      55         177 :   return function->ablocks[0].size();
      56             : }
      57             : 
      58        5813 : unsigned AdjacencyMatrixVessel::getNumberOfColumns() const {
      59        5813 :   return function->ablocks[1].size();
      60             : }
      61             : 
      62       10864 : bool AdjacencyMatrixVessel::matrixElementIsActive( const unsigned& ielem, const unsigned& jelem ) const {
      63       10864 :   return StoreDataVessel::storedValueIsActive( getStoreIndexFromMatrixIndices( ielem, jelem ) );
      64             : }
      65             : 
      66       21728 : unsigned AdjacencyMatrixVessel::getStoreIndexFromMatrixIndices( const unsigned& ielem, const unsigned& jelem ) const {
      67       21728 :   if( !symmetric && !hbonds ) return (function->ablocks[1].size())*ielem + jelem;
      68       19728 :   if( !symmetric ) {
      69             :     plumed_dbg_assert( ielem!=jelem );
      70       16128 :     if( jelem<ielem ) return (function->ablocks[1].size()-1)*ielem + jelem;
      71        8064 :     return (function->ablocks[1].size()-1)*ielem + jelem - 1;
      72             :   }
      73        3600 :   if( ielem>jelem ) return 0.5*ielem*(ielem-1)+jelem;
      74        1800 :   return 0.5*jelem*(jelem-1) + ielem;
      75             : }
      76             : 
      77           6 : AdjacencyMatrixBase* AdjacencyMatrixVessel::getMatrixAction() {
      78           6 :   return function;
      79             : }
      80             : 
      81       11708 : void AdjacencyMatrixVessel::getMatrixIndices( const unsigned& code, unsigned& i, unsigned& j ) const {
      82       11708 :   std::vector<unsigned> myatoms; function->decodeIndexToAtoms( function->getTaskCode(code), myatoms );
      83       11708 :   i=myatoms[0]; j=myatoms[1];
      84       11708 :   if( !undirectedGraph() ) j -= function->ablocks[0].size(); // Have to remove number of columns as returns number in ablocks[1]
      85       11708 : }
      86             : 
      87          17 : void AdjacencyMatrixVessel::retrieveMatrix( DynamicList<unsigned>& myactive_elements, Matrix<double>& mymatrix ) {
      88             :   unsigned vin; double df;
      89          17 :   myactive_elements.deactivateAll(); std::vector<double> vals( getNumberOfComponents() );
      90        1564 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
      91        1547 :     retrieveSequentialValue( i, false, vals );
      92        1547 :     if( vals[0]<epsilon ) continue ;
      93             : 
      94        1547 :     myactive_elements.activate(i);
      95        1547 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
      96             : 
      97        1547 :     if( symmetric ) mymatrix(k,j)=mymatrix(j,k)=vals[0]*function->transformStoredValues( vals, vin, df );
      98           0 :     else mymatrix(k,j)=vals[0]*function->transformStoredValues( vals, vin, df );
      99             :   }
     100          17 :   myactive_elements.updateActiveMembers();
     101          17 : }
     102             : 
     103          15 : void AdjacencyMatrixVessel::retrieveAdjacencyLists( std::vector<unsigned>& nneigh, Matrix<unsigned>& adj_list ) {
     104             :   plumed_dbg_assert( undirectedGraph() );
     105             :   // Currently everything has zero neighbors
     106          15 :   for(unsigned i=0; i<nneigh.size(); ++i) nneigh[i]=0;
     107             : 
     108             :   // And set up the adjacency list
     109          15 :   std::vector<double> myvals( getNumberOfComponents() );
     110       89662 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
     111             :     // Check if atoms are connected
     112       89647 :     retrieveSequentialValue( i, false, myvals );
     113       89647 :     if( myvals[0]<epsilon || !function->checkForConnection( myvals ) ) continue ;
     114             : 
     115        8614 :     unsigned j, k; getMatrixIndices( function->getPositionInFullTaskList(i), k, j );
     116             : 
     117        8614 :     if( nneigh[j]>=adj_list.ncols() || nneigh[k]>=adj_list.ncols() ) error("adjacency lists are not large enough, increase maxconnections");
     118             :     // Store if atoms are connected
     119             :     // unsigned j, k; getMatrixIndices( i, k, j );
     120        8614 :     adj_list(k,nneigh[k])=j; nneigh[k]++;
     121        8614 :     adj_list(j,nneigh[j])=k; nneigh[j]++;
     122          15 :   }
     123          15 : }
     124             : 
     125           0 : void AdjacencyMatrixVessel::retrieveEdgeList( unsigned& nedge, std::vector<std::pair<unsigned,unsigned> >& edge_list ) {
     126           0 :   plumed_dbg_assert( undirectedGraph() ); nedge=0;
     127           0 :   std::vector<double> myvals( getNumberOfComponents() );
     128           0 :   if( getNumberOfStoredValues()>edge_list.size() ) error("adjacency lists are not large enough, increase maxconnections");
     129             : 
     130           0 :   for(unsigned i=0; i<getNumberOfStoredValues(); ++i) {
     131             :     // Check if atoms are connected
     132           0 :     retrieveSequentialValue( i, false, myvals );
     133           0 :     if( myvals[0]<epsilon || !function->checkForConnection( myvals ) ) continue ;
     134             : 
     135           0 :     getMatrixIndices( function->getPositionInFullTaskList(i), edge_list[nedge].first, edge_list[nedge].second );
     136           0 :     nedge++;
     137           0 :   }
     138           0 : }
     139             : 
     140           0 : bool AdjacencyMatrixVessel::nodesAreConnected( const unsigned& iatom, const unsigned& jatom ) const {
     141           0 :   if( !matrixElementIsActive( iatom, jatom ) ) return false;
     142           0 :   unsigned ind=getStoreIndexFromMatrixIndices( iatom, jatom );
     143             : 
     144           0 :   std::vector<double> myvals( getNumberOfComponents() );
     145           0 :   retrieveValueWithIndex( ind, false, myvals );
     146           0 :   return ( myvals[0]>epsilon && function->checkForConnection( myvals ) );
     147             : }
     148             : 
     149       23058 : void AdjacencyMatrixVessel::retrieveDerivatives( const unsigned& myelem, const bool& normed, MultiValue& myvals ) {
     150       23058 :   StoreDataVessel::retrieveDerivatives( myelem, normed, myvals );
     151       46116 :   if( !function->weightHasDerivatives ) return ;
     152             : 
     153           0 :   unsigned vi; std::vector<double> vals( getNumberOfComponents() ); retrieveValueWithIndex( myelem, normed, vals );
     154           0 :   double df, max=function->transformStoredValues( vals, vi, df );
     155             : 
     156           0 :   double pref = max/(vals[0]*vals[0]);
     157           0 :   for(unsigned i=0; i<myvals.getNumberActive(); ++i) {
     158           0 :     unsigned jder=myvals.getActiveIndex(i);
     159           0 :     myvals.setDerivative( 1, jder, df*myvals.getDerivative(vi, jder)/vals[0] - pref*myvals.getDerivative(0, jder) );
     160           0 :   }
     161             : }
     162             : 
     163       21658 : void AdjacencyMatrixVessel::recalculateStoredQuantity( const unsigned& myelem, MultiValue& myvals ) {
     164       21658 :   function->recalculateMatrixElement( myelem, myvals );
     165       21658 : }
     166             : 
     167           4 : double AdjacencyMatrixVessel::getCutoffForConnection() const {
     168           4 :   return function->getLinkCellCutoff();
     169             : }
     170             : 
     171             : }
     172        2523 : }
     173             : 

Generated by: LCOV version 1.13