LCOV - code coverage report
Current view: top level - reference - DRMSD.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 55 55 100.0 %
Date: 2020-11-18 11:20:57 Functions: 13 13 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2013-2019 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 "DRMSD.h"
      23             : #include "MetricRegister.h"
      24             : #include "tools/Pbc.h"
      25             : 
      26             : namespace PLMD {
      27             : 
      28        6478 : PLUMED_REGISTER_METRIC(DRMSD,"DRMSD")
      29             : 
      30          28 : DRMSD::DRMSD( const ReferenceConfigurationOptions& ro ):
      31             :   ReferenceConfiguration( ro ),
      32             :   SingleDomainRMSD( ro ),
      33             :   nopbc(true),
      34             :   bounds_were_set(false),
      35             :   lower(0),
      36          28 :   upper(std::numeric_limits<double>::max( ))
      37             : {
      38          28 : }
      39             : 
      40          39 : void DRMSD::setBoundsOnDistances( bool dopbc, double lbound, double ubound ) {
      41          39 :   bounds_were_set=true; nopbc=!dopbc;
      42          39 :   lower=lbound; upper=ubound;
      43          39 : }
      44             : 
      45          11 : void DRMSD::readBounds() {
      46          22 :   parseFlag("NOPBC",nopbc);
      47          22 :   parse("LOWER_CUTOFF",lower,true);
      48          22 :   parse("UPPER_CUTOFF",upper,true);
      49          11 :   setBoundsOnDistances( !nopbc, lower, upper );
      50          11 : }
      51             : 
      52           9 : void DRMSD::read( const PDB& pdb ) {
      53           9 :   readAtomsFromPDB( pdb ); readBounds(); setup_targets();
      54           9 : }
      55             : 
      56          17 : void DRMSD::setReferenceAtoms( const std::vector<Vector>& conf, const std::vector<double>& align_in, const std::vector<double>& displace_in ) {
      57          17 :   SingleDomainRMSD::setReferenceAtoms( conf, align_in, displace_in );
      58          17 :   setup_targets();
      59          17 : }
      60             : 
      61          26 : void DRMSD::setup_targets() {
      62          26 :   plumed_massert( bounds_were_set, "I am missing a call to DRMSD::setBoundsOnDistances");
      63             : 
      64          26 :   unsigned natoms = getNumberOfReferencePositions();
      65         569 :   for(unsigned i=0; i<natoms-1; ++i) {
      66        7779 :     for(unsigned j=i+1; j<natoms; ++j) {
      67        7236 :       double distance = delta( getReferencePosition(i), getReferencePosition(j) ).modulo();
      68        7236 :       if(distance < upper && distance > lower ) {
      69        6620 :         targets[std::make_pair(i,j)] = distance;
      70             :       }
      71             :     }
      72             :   }
      73          26 :   if( targets.empty() ) error("drmsd will compare no distances - check upper and lower bounds are sensible");
      74          26 : }
      75             : 
      76       20378 : double DRMSD::calc( const std::vector<Vector>& pos, const Pbc& pbc, ReferenceValuePack& myder, const bool& squared ) const {
      77             :   plumed_dbg_assert(!targets.empty());
      78             : 
      79       20378 :   Vector distance;
      80       20378 :   myder.clear();
      81             :   double drmsd=0.;
      82     8126088 :   for(const auto & it : targets) {
      83             : 
      84     8105710 :     const unsigned i=getAtomIndex( it.first.first );
      85     8105710 :     const unsigned j=getAtomIndex( it.first.second );
      86             : 
      87     8164510 :     if(nopbc) distance=delta( pos[i], pos[j] );
      88    24228930 :     else      distance=pbc.distance( pos[i], pos[j] );
      89             : 
      90     8105710 :     const double len = distance.modulo();
      91     8105710 :     const double diff = len - it.second;
      92     8105710 :     const double der = diff / len;
      93             : 
      94     8105710 :     drmsd += diff * diff;
      95     8105710 :     myder.addAtomDerivatives( i, -der * distance );
      96     8105710 :     myder.addAtomDerivatives( j,  der * distance );
      97     8105710 :     myder.addBoxDerivatives( - der * Tensor(distance,distance) );
      98             :   }
      99             : 
     100       20378 :   const double inpairs = 1./static_cast<double>(targets.size());
     101             :   double idrmsd;
     102             : 
     103       20378 :   if(squared) {
     104          10 :     drmsd = drmsd * inpairs;
     105          10 :     idrmsd = 2.0 * inpairs;
     106             :   } else {
     107       20368 :     drmsd = sqrt( drmsd * inpairs );
     108       20368 :     idrmsd = inpairs / drmsd ;
     109             :   }
     110             : 
     111       20378 :   myder.scaleAllDerivatives( idrmsd );
     112             : 
     113       20378 :   return drmsd;
     114             : }
     115             : 
     116        4839 : }

Generated by: LCOV version 1.13