LCOV - code coverage report
Current view: top level - mapping - PathReparameterization.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 65 65 100.0 %
Date: 2024-10-11 08:09:47 Functions: 5 5 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2016-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 "PathReparameterization.h"
      23             : 
      24             : namespace PLMD {
      25             : namespace mapping {
      26             : 
      27           4 : PathReparameterization::PathReparameterization( const Pbc& ipbc, const std::vector<Value*>& iargs, std::vector<std::unique_ptr<ReferenceConfiguration>>& pp ):
      28           4 :   mydpack( 1, pp[0]->getNumberOfReferenceArguments() + 3*pp[0]->getNumberOfReferencePositions() + 9 ),
      29           4 :   mypack( pp[0]->getNumberOfReferenceArguments(), pp[0]->getNumberOfReferencePositions(), mydpack ),
      30           8 :   mydir(ReferenceConfigurationOptions("DIRECTION")),
      31           4 :   pbc(ipbc),
      32           4 :   args(iargs),
      33           4 :   mypath(pp),
      34           4 :   len(pp.size()),
      35           4 :   sumlen(pp.size()),
      36           4 :   sfrac(pp.size()),
      37           8 :   MAXCYCLES(100)
      38             : {
      39           4 :   mypdb.setAtomNumbers(  pp[0]->getAbsoluteIndexes() ); mypdb.addBlockEnd( pp[0]->getAbsoluteIndexes().size() );
      40           4 :   if( pp[0]->getArgumentNames().size()>0 ) mypdb.setArgumentNames( pp[0]->getArgumentNames() );
      41           4 :   mydir.read( mypdb ); mydir.zeroDirection(); pp[0]->setupPCAStorage( mypack );
      42           4 : }
      43             : 
      44        1741 : bool PathReparameterization::loopEnd( const int& index, const int& end, const int& inc ) const {
      45        1741 :   if( inc>0 && index<end ) return false;
      46         270 :   else if( inc<0 && index>end ) return false;
      47             :   return true;
      48             : }
      49             : 
      50          71 : void PathReparameterization::calcCurrentPathSpacings( const int& istart, const int& iend ) {
      51             :   plumed_dbg_assert( istart<len.size() && iend<len.size() );
      52          71 :   len[istart] = sumlen[istart]=0;
      53             :   //printf("HELLO PATH SPACINGS ARE CURRENTLY \n");
      54             : 
      55             :   // Get the spacings given we can go forward and backwards
      56          71 :   int incr=1; if( istart>iend ) { incr=-1; }
      57             : 
      58         657 :   for(int i=istart+incr; loopEnd(i,iend+incr,incr)==false; i+=incr) {
      59         586 :     len[i] = mypath[i-incr]->calc( mypath[i]->getReferencePositions(), pbc, args, mypath[i]->getReferenceArguments(), mypack, false );
      60         586 :     sumlen[i] = sumlen[i-incr] + len[i];
      61             :     //printf("FRAME %d TO FRAME %d EQUALS %f : %f \n",i-incr,i,len[i],sumlen[i] );
      62             :   }
      63          71 : }
      64             : 
      65          10 : void PathReparameterization::reparameterizePart( const int& istart, const int& iend, const double& target, const double& TOL ) {
      66          10 :   calcCurrentPathSpacings( istart, iend ); unsigned cfin;
      67             :   // If a target separation is set we fix where we want the nodes
      68          10 :   int incr=1; if( istart>iend ) { incr=-1; }
      69             : 
      70          10 :   if( target>0 ) {
      71           6 :     if( iend>istart ) {
      72          19 :       for(unsigned i=istart; i<iend+1; ++i) sfrac[i] = target*(i-istart);
      73             :     } else {
      74          14 :       for(int i=istart-1; i>iend-1; --i) sfrac[i]=target*(istart-i);
      75             :     }
      76           6 :     cfin = iend+incr;
      77             :   } else {
      78           4 :     cfin = iend;
      79             :   }
      80             : 
      81             :   std::vector<Direction> newpath;
      82         170 :   for(unsigned i=0; i<mypath.size(); ++i) {
      83         320 :     newpath.push_back( Direction(ReferenceConfigurationOptions("DIRECTION")) ); newpath[i].read( mypdb );
      84             :   }
      85             : 
      86             :   double prevsum=0.;
      87          71 :   for(unsigned iter=0; iter<MAXCYCLES; ++iter) {
      88          71 :     if( std::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        2567 :       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         481 :       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         481 :       newpath[i].setDirection( mypath[k]->getReferencePositions(), mypath[k]->getReferenceArguments() );
     111             :       // Get the displacement of the path
     112         481 :       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 amount
     116         481 :       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         481 :       mypdb.setAtomPositions( newpath[i].getReferencePositions() );
     122        1415 :       for(unsigned j=0; j<newpath[i].getNumberOfReferenceArguments(); ++j) mypdb.setArgumentValue( mypath[i]->getArgumentNames()[j], newpath[i].getReferenceArgument(j) );
     123         481 :       mypath[i]->read( mypdb );
     124             :     }
     125             : 
     126             :     // Recompute the separations between frames
     127          61 :     calcCurrentPathSpacings( istart, iend );
     128             :   }
     129          10 : }
     130             : 
     131           4 : void PathReparameterization::reparameterize( const int& ifix1, const int& ifix2, const double& TOL ) {
     132             :   plumed_dbg_assert( ifix1<ifix2 );
     133             :   // First reparameterize the part between the fixed frames
     134           4 :   reparameterizePart( ifix1, ifix2, -1.0, TOL );
     135             : 
     136             :   // Get the separation between frames which we will use to set the remaining frames
     137           4 :   double target = sumlen[ifix2] / ( ifix2 - ifix1 );
     138             : 
     139             :   // And reparameterize the beginning and end of the path
     140           4 :   if( ifix1>0 ) reparameterizePart( ifix1, 0, target, TOL );
     141           4 :   if( ifix2<(mypath.size()-1) ) reparameterizePart( ifix2, mypath.size()-1, target, TOL );
     142             : //  calcCurrentPathSpacings( 0, mypath.size()-1 );
     143           4 : }
     144             : 
     145             : }
     146             : }

Generated by: LCOV version 1.15