LCOV - code coverage report
Current view: top level - function - SortWithSingleArgument.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 45 49 91.8 %
Date: 2026-11-05 10:19:04 Functions: 7 8 87.5 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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 "core/ActionWithArguments.h"
      23             : #include "core/ActionWithValue.h"
      24             : #include "core/ActionRegister.h"
      25             : 
      26             : 
      27             : namespace PLMD {
      28             : namespace function {
      29             : 
      30             : class SortWithSingleArgument :
      31             :   public ActionWithValue,
      32             :   public ActionWithArguments {
      33             : private:
      34             :   void sortData( std::vector<std::pair<double,int> >& data );
      35             : public:
      36             :   static void registerKeywords(Keywords& keys);
      37             :   explicit SortWithSingleArgument(const ActionOptions&);
      38             :   unsigned getNumberOfDerivatives() override ;
      39             :   std::string getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const override ;
      40             :   void calculate() override ;
      41             :   void apply() override ;
      42             : };
      43             : 
      44             : PLUMED_REGISTER_ACTION(SortWithSingleArgument,"SORT_ONEARG")
      45             : 
      46          27 : void SortWithSingleArgument::registerKeywords(Keywords& keys) {
      47          27 :   Action::registerKeywords(keys);
      48          27 :   ActionWithValue::registerKeywords(keys);
      49          27 :   ActionWithArguments::registerKeywords(keys);
      50          27 :   keys.setDisplayName("SORT");
      51          54 :   keys.addInputKeyword("compulsory","ARG","vector","the vector whose elements we are sorting");
      52          54 :   keys.setValueDescription("vector","sorted");
      53          27 :   keys.setComponentsIntroduction("The names of the components in this action will be customized in accordance with the contents of the input file. "
      54             :                                  "The smallest value is called label.1, the second smallest label.2, the third smallest label.3 and so on");
      55          27 : }
      56             : 
      57          11 : SortWithSingleArgument::SortWithSingleArgument(const ActionOptions&ao):
      58             :   Action(ao),
      59             :   ActionWithValue(ao),
      60          11 :   ActionWithArguments(ao) {
      61             : 
      62          11 :   if( getNumberOfArguments()!=1 ) {
      63           0 :     error("should only be one argument in input for this action");
      64             :   }
      65          11 :   if( getPntrToArgument(0)->getRank()!=1 || getPntrToArgument(0)->hasDerivatives() ) {
      66           0 :     error("input to sort should be list of values of single vector");
      67             :   }
      68             : 
      69             :   std::string smin, smax;
      70          11 :   if( getPntrToArgument(0)->isPeriodic() ) {
      71           0 :     getPntrToArgument(0)->getDomain( smin, smax );
      72             :   }
      73             : 
      74         116 :   for(unsigned i=0; i<getPntrToArgument(0)->getShape()[0]; ++i) {
      75             :     std::string num;
      76         105 :     Tools::convert(i+1, num );
      77         105 :     addComponent( num );
      78         105 :     if( getPntrToArgument(0)->isPeriodic() ) {
      79           0 :       componentIsPeriodic( num, smin, smax );
      80             :     } else {
      81         105 :       componentIsNotPeriodic( num );
      82             :     }
      83             :   }
      84          11 : }
      85             : 
      86           3 : std::string SortWithSingleArgument::getOutputComponentDescription( const std::string& cname, const Keywords& keys ) const {
      87           6 :   return "the " + cname + "th smallest element in the input vector";
      88             : }
      89             : 
      90         274 : unsigned SortWithSingleArgument::getNumberOfDerivatives() {
      91         274 :   return 0;
      92             : }
      93             : 
      94         189 : void SortWithSingleArgument::sortData( std::vector<std::pair<double,int> >& data ) {
      95             :   const Value* myarg = getPntrToArgument(0);
      96        1982 :   for(unsigned i=0; i<data.size(); ++i) {
      97        1793 :     data[i].first = myarg->get(i);
      98        1793 :     data[i].second = i;
      99             :   }
     100         189 :   std::sort( data.begin(), data.end());
     101         189 : }
     102             : 
     103         103 : void SortWithSingleArgument::calculate() {
     104         103 :   std::vector<std::pair<double,int> > data( getPntrToArgument(0)->getShape()[0] );
     105         103 :   sortData( data );
     106             : 
     107        1059 :   for(unsigned i=0; i<data.size(); ++i) {
     108         956 :     getPntrToComponent(i)->set( data[i].first );
     109             :   }
     110         103 : }
     111             : 
     112         103 : void SortWithSingleArgument::apply() {
     113             :   // Forces may have been added to any of the components (e.g. only to label.4)
     114             :   bool hasforces=false;
     115         225 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
     116         208 :     if( getPntrToComponent(i)->forcesWereAdded() ) {
     117             :       hasforces=true;
     118             :       break;
     119             :     }
     120             :   }
     121         103 :   if( !hasforces ) {
     122          17 :     return ;
     123             :   }
     124          86 :   std::vector<std::pair<double,int> > data( getPntrToArgument(0)->getShape()[0] );
     125          86 :   sortData( data );
     126             : 
     127             :   Value* myarg = getPntrToArgument(0);
     128         923 :   for(unsigned i=0; i<data.size(); ++i) {
     129         837 :     myarg->addForce( data[i].second, getPntrToComponent(i)->getForce() );
     130             :   }
     131             : }
     132             : 
     133             : }
     134             : 
     135             : 
     136             : }

Generated by: LCOV version 1.16