LCOV - code coverage report
Current view: top level - generic - Constant.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 87 95 91.6 %
Date: 2026-03-30 11:13:23 Functions: 3 7 42.9 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2011-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 "core/ActionWithValue.h"
      23             : #include "core/ActionRegister.h"
      24             : #include "tools/IFile.h"
      25             : 
      26             : //+PLUMEDOC COLVAR CONSTANT
      27             : /*
      28             : Create a constant value that can be passed to actions
      29             : 
      30             : Useful in combination with functions that
      31             : takes in input constants or parameters.
      32             : 
      33             : \par Examples
      34             : 
      35             : The following input instructs plumed to compute the distance
      36             : between atoms 1 and 2. If this distance is between 1.0 and 2.0, it is
      37             : printed. If it is lower than 1.0 (larger than 2.0), 1.0 (2.0) is printed
      38             : 
      39             : \plumedfile
      40             : cn: CONSTANT VALUES=1.0,2.0
      41             : dis: DISTANCE ATOMS=1,2
      42             : sss: SORT ARG=cn.v-0,dis,cn.v-1
      43             : PRINT ARG=sss.2
      44             : \endplumedfile
      45             : 
      46             : In case you want to pass a single value you can use VALUE:
      47             : \plumedfile
      48             : cn: CONSTANT VALUE=1.0
      49             : dis: DISTANCE ATOMS=1,2
      50             : sss: SORT ARG=cn,dis
      51             : PRINT ARG=sss.1
      52             : \endplumedfile
      53             : 
      54             : */
      55             : //+ENDPLUMEDOC
      56             : 
      57             : namespace PLMD {
      58             : namespace generic {
      59             : 
      60             : class Constant : public ActionWithValue {
      61             : public:
      62             :   static void registerKeywords( Keywords& keys );
      63             :   explicit Constant(const ActionOptions&ao);
      64           0 :   void clearDerivatives( const bool& force=false ) {}
      65        6041 :   unsigned getNumberOfDerivatives() override {
      66        6041 :     return 0;
      67             :   }
      68           0 :   void calculate() override {}
      69           0 :   void apply() override {}
      70             : };
      71             : 
      72             : PLUMED_REGISTER_ACTION(Constant,"CONSTANT")
      73             : 
      74        1510 : void Constant::registerKeywords( Keywords& keys ) {
      75        1510 :   Action::registerKeywords(keys);
      76        1510 :   ActionWithValue::registerKeywords(keys);
      77        1510 :   keys.remove("NUMERICAL_DERIVATIVES");
      78        3020 :   keys.add("optional","FILE","an input file containing the matrix");
      79        3020 :   keys.add("compulsory","NROWS","0","the number of rows in your input matrix");
      80        3020 :   keys.add("compulsory","NCOLS","0","the number of columns in your matrix");
      81        3020 :   keys.add("optional","VALUE","the single number that you would like to store");
      82        3020 :   keys.add("optional","VALUES","the numbers that are in your constant value");
      83        3020 :   keys.addFlag("SCALARS",false,"treat the input list of numbers as a set of scalars");
      84        3020 :   keys.addFlag("NOLOG",false,"do not report all the read in scalars in the log");
      85        3020 :   keys.addOutputComponent("v","SCALARS","the # value");
      86        1510 :   keys.setValueDescription("the constant value that was read from the plumed input");
      87        1510 : }
      88             : 
      89         851 : Constant::Constant(const ActionOptions&ao):
      90             :   Action(ao),
      91         851 :   ActionWithValue(ao) {
      92         851 :   bool nolog=false;
      93         851 :   parseFlag("NOLOG",nolog);
      94         851 :   bool scalars=false;
      95             :   std::string fname, vname;
      96        1702 :   parse("FILE",fname);
      97             :   std::vector<unsigned> shape;
      98             :   std::vector<double> vals;
      99         851 :   if( fname.length()>0 ) {
     100           3 :     IFile mfile;
     101           3 :     mfile.open(fname);
     102             :     // Read in first line
     103             :     std::vector<std::string> words;
     104             :     unsigned nline=0;
     105           6 :     while( nline==0 ) {
     106           3 :       Tools::getParsedLine( mfile, words );
     107           3 :       nline=words.size();
     108             :     }
     109             :     std::vector<std::vector<double> > dissimilarities;
     110           3 :     if( nline==1 ) {
     111           0 :       shape.resize(1);
     112           0 :       error("invalid matrix in input file");
     113             :     }
     114           3 :     shape.resize(2);
     115           3 :     shape[1]=nline;
     116           3 :     std::vector<double> tmpdis( shape[1] );
     117          34 :     for(unsigned j=0; j<shape[1]; ++j) {
     118          31 :       Tools::convert( words[j], tmpdis[j] );
     119             :     }
     120           3 :     dissimilarities.push_back( tmpdis );
     121             : 
     122          31 :     while( Tools::getParsedLine( mfile, words ) ) {
     123          28 :       if( words.size()!=nline ) {
     124           0 :         error("bad formatting in matrix file");
     125             :       }
     126         360 :       for(unsigned j=0; j<nline; ++j) {
     127         332 :         Tools::convert( words[j], tmpdis[j] );
     128             :       }
     129          28 :       dissimilarities.push_back( tmpdis );
     130             :     }
     131           3 :     mfile.close();
     132           3 :     shape[0] = dissimilarities.size();
     133           3 :     vals.resize(shape[0]);
     134           3 :     if( shape.size()==2 ) {
     135           3 :       vals.resize( shape[0]*shape[1] );
     136             :     }
     137          34 :     for(unsigned i=0; i<shape[0]; ++i) {
     138         394 :       for(unsigned j=0; j<nline; ++j) {
     139         363 :         vals[i*nline+j] = dissimilarities[i][j];
     140             :       }
     141             :     }
     142           3 :   } else {
     143             :     unsigned nr, nc;
     144         848 :     parse("NROWS",nr);
     145         848 :     parse("NCOLS",nc);
     146         848 :     if( nr>0 && nc>0 ) {
     147          73 :       shape.resize(2);
     148          73 :       shape[0]=nr;
     149          73 :       shape[1]=nc;
     150          73 :       vals.resize( nr*nc );
     151          73 :       log.printf("  reading in %d by %d matrix \n", nr, nc );
     152         775 :     } else if( nr>0 || nc>0 ) {
     153           0 :       error("makes no sense to set only one of NROWS and NCOLS to a non-zero value");
     154             :     }
     155         848 :     parseVector("VALUES",vals);
     156        1696 :     parseFlag("SCALARS",scalars);
     157         848 :     if( vals.size()==0 ) {
     158         132 :       parseVector("VALUE",vals);
     159          66 :       if( vals.size()!=1 ) {
     160           0 :         error("VALUE keyword should take a single scalar");
     161             :       }
     162         782 :     } else if( vals.size()==1 ) {
     163         236 :       scalars=false;
     164             :     }
     165             : 
     166         848 :     log.printf("  read in %d values :", vals.size() );
     167         848 :     if( !nolog ) {
     168       25705 :       for(unsigned i=0; i<vals.size(); ++i) {
     169       25112 :         log.printf(" %f", vals[i] );
     170             :       }
     171             :     }
     172         848 :     log.printf("\n");
     173         848 :     if( !scalars && shape.size()==0 && vals.size()>1 ) {
     174         472 :       shape.resize(1);
     175         472 :       shape[0] = vals.size();
     176             :     }
     177             :   }
     178         851 :   if( !scalars ) {
     179             :     // Now set the value
     180         850 :     addValue( shape );
     181         850 :     setNotPeriodic();
     182         850 :     getPntrToComponent(0)->setConstant();
     183      147242 :     for(unsigned i=0; i<vals.size(); ++i) {
     184      146392 :       getPntrToComponent(0)->set( i, vals[i] );
     185             :     }
     186             :   } else {
     187           3 :     for(unsigned i=0; i<vals.size(); i++) {
     188             :       std::string num;
     189           2 :       Tools::convert(i,num);
     190           4 :       addComponent("v-"+num);
     191           2 :       componentIsNotPeriodic("v-"+num);
     192           2 :       Value* comp=getPntrToComponent("v-"+num);
     193           2 :       comp->setConstant();
     194           2 :       comp->set(vals[i]);
     195             :     }
     196             :   }
     197         851 : }
     198             : 
     199             : }
     200             : }
     201             : 

Generated by: LCOV version 1.16