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

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-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 "PathReparameterization.h"
      23             : 
      24             : namespace PLMD {
      25             : namespace mapping {
      26             : 
      27           4 : PathReparameterization::PathReparameterization( const Pbc& ipbc, const std::vector<Value*>& iargs, std::vector<ReferenceConfiguration*>& pp ):
      28          12 :   mydpack( 1, pp[0]->getNumberOfReferenceArguments() + 3*pp[0]->getNumberOfReferencePositions() + 9 ),
      29          12 :   mypack( pp[0]->getNumberOfReferenceArguments(), pp[0]->getNumberOfReferencePositions(), mydpack ),
      30             :   mypath(pp),
      31             :   pbc(ipbc),
      32             :   args(iargs),
      33          12 :   mydir(ReferenceConfigurationOptions("DIRECTION")),
      34             :   len(pp.size()),
      35             :   sumlen(pp.size()),
      36             :   sfrac(pp.size()),
      37          40 :   MAXCYCLES(100)
      38             : {
      39          12 :   mydir.setNamesAndAtomNumbers( pp[0]->getAbsoluteIndexes(), pp[0]->getArgumentNames() );
      40           8 :   mydir.zeroDirection(); pp[0]->setupPCAStorage( mypack );
      41           4 : }
      42             : 
      43        1741 : bool PathReparameterization::loopEnd( const int& index, const int& end, const int& inc ) const {
      44        1741 :   if( inc>0 && index<end ) return false;
      45         270 :   else if( inc<0 && index>end ) return false;
      46         193 :   return true;
      47             : }
      48             : 
      49          71 : void PathReparameterization::calcCurrentPathSpacings( const int& istart, const int& iend ) {
      50             :   plumed_dbg_assert( istart<len.size() && iend<len.size() );
      51         213 :   len[istart] = sumlen[istart]=0;
      52             :   //printf("HELLO PATH SPACINGS ARE CURRENTLY \n");
      53             : 
      54             :   // Get the spacings given we can go forward and backwards
      55          71 :   int incr=1; if( istart>iend ) { incr=-1; }
      56             : 
      57         657 :   for(int i=istart+incr; loopEnd(i,iend+incr,incr)==false; i+=incr) {
      58        2930 :     len[i] = mypath[i-incr]->calc( mypath[i]->getReferencePositions(), pbc, args, mypath[i]->getReferenceArguments(), mypack, false );
      59        2344 :     sumlen[i] = sumlen[i-incr] + len[i];
      60             :     //printf("FRAME %d TO FRAME %d EQUALS %f : %f \n",i-incr,i,len[i],sumlen[i] );
      61             :   }
      62          71 : }
      63             : 
      64          10 : void PathReparameterization::reparameterizePart( const int& istart, const int& iend, const double& target, const double& TOL ) {
      65          10 :   calcCurrentPathSpacings( istart, iend ); unsigned cfin;
      66             :   // If a target separation is set we fix where we want the nodes
      67          10 :   int incr=1; if( istart>iend ) { incr=-1; }
      68             : 
      69          10 :   if( target>0 ) {
      70           6 :     if( iend>istart ) {
      71          19 :       for(unsigned i=istart; i<iend+1; ++i) sfrac[i] = target*(i-istart);
      72             :     } else {
      73          14 :       for(int i=istart-1; i>iend-1; --i) sfrac[i]=target*(istart-i);
      74             :     }
      75           6 :     cfin = iend+incr;
      76             :   } else {
      77           4 :     cfin = iend;
      78             :   }
      79             : 
      80          10 :   std::vector<Direction> newpath;
      81         500 :   for(unsigned i=0; i<mypath.size(); ++i) {
      82         640 :     newpath.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")) );
      83         480 :     newpath[i].setNamesAndAtomNumbers( mypath[i]->getAbsoluteIndexes(), mypath[i]->getArgumentNames() );
      84             :   }
      85             : 
      86             :   double prevsum=0.;
      87         132 :   for(unsigned iter=0; iter<MAXCYCLES; ++iter) {
      88         142 :     if( fabs(sumlen[iend] - prevsum)<=TOL ) break ;
      89             :     prevsum = sumlen[iend];
      90             :     // If no target is set we redistribute length
      91          61 :     if( target<0 ) {
      92          49 :       plumed_assert( istart<iend );
      93          49 :       double dr = sumlen[iend] / static_cast<double>( iend - istart );
      94         531 :       for(unsigned i=istart; i<iend; ++i) sfrac[i] = dr*(i-istart);
      95             :     }
      96             : 
      97             :     // Now compute positions of new nodes in path
      98         542 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
      99         481 :       int k = istart;
     100       10268 :       while( !((sumlen[k] < sfrac[i]) && (sumlen[k+incr]>=sfrac[i])) ) {
     101        2093 :         k+=incr;
     102        2093 :         if( cfin==iend && k>= iend+1 ) plumed_merror("path reparameterization error");
     103        2093 :         else if( cfin==(iend+1) && k>=iend ) { k=iend-1; break; }
     104        2090 :         else if( cfin==(iend-1) && k<=iend ) { k=iend+1; break; }
     105             :       }
     106        1443 :       double dr = (sfrac[i]-sumlen[k])/len[k+incr];
     107             :       // Calculate the displacement between the appropriate points
     108             :       // double dd = mypath[k]->calc( mypath[k+incr]->getReferencePositions(), pbc, args, mypath[k+incr]->getReferenceArguments(), mypack, true );
     109             :       // Copy the reference configuration from the configuration to a tempory direction
     110        1443 :       newpath[i].setDirection( mypath[k]->getReferencePositions(), mypath[k]->getReferenceArguments() );
     111             :       // Get the displacement of the path
     112        1924 :       mypath[k]->extractDisplacementVector( mypath[k+incr]->getReferencePositions(), args, mypath[k+incr]->getReferenceArguments(), false, mydir );
     113             :       // Set our direction equal to the displacement
     114             :       // mydir.setDirection( mypack );
     115             :       // Shift the reference configuration by this ammount
     116         962 :       newpath[i].displaceReferenceConfiguration( dr, mydir );
     117             :     }
     118             : 
     119             :     // Copy the positions of the new path to the new paths
     120         542 :     for(int i=istart+incr; loopEnd(i,cfin,incr)==false; i+=incr) {
     121        1924 :       mypath[i]->setReferenceConfig( newpath[i].getReferencePositions(), newpath[i].getReferenceArguments(), mypath[i]->getReferenceMetric() );
     122             :     }
     123             : 
     124             :     // Recompute the separations between frames
     125          61 :     calcCurrentPathSpacings( istart, iend );
     126             :   }
     127          10 : }
     128             : 
     129           4 : void PathReparameterization::reparameterize( const int& ifix1, const int& ifix2, const double& TOL ) {
     130             :   plumed_dbg_assert( ifix1<ifix2 );
     131             :   // First reparameterize the part between the fixed frames
     132           4 :   reparameterizePart( ifix1, ifix2, -1.0, TOL );
     133             : 
     134             :   // Get the separation between frames which we will use to set the remaining frames
     135           8 :   double target = sumlen[ifix2] / ( ifix2 - ifix1 );
     136             : 
     137             :   // And reparameterize the begining and end of the path
     138           4 :   if( ifix1>0 ) reparameterizePart( ifix1, 0, target, TOL );
     139           8 :   if( ifix2<(mypath.size()-1) ) reparameterizePart( ifix2, mypath.size()-1, target, TOL );
     140             : //  calcCurrentPathSpacings( 0, mypath.size()-1 );
     141           4 : }
     142             : 
     143             : }
     144        4839 : }

Generated by: LCOV version 1.13