LCOV - code coverage report
Current view: top level - core - ActionToPutData.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 97 105 92.4 %
Date: 2024-10-18 14:00:25 Functions: 17 17 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2017-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 "ActionToPutData.h"
      23             : #include "ActionRegister.h"
      24             : #include "PlumedMain.h"
      25             : #include "ActionSet.h"
      26             : 
      27             : //+PLUMEDOC ANALYSIS PUT
      28             : /*
      29             : Pass data into PLUMED
      30             : 
      31             : \par Examples
      32             : 
      33             : */
      34             : //+ENDPLUMEDOC
      35             : 
      36             : namespace PLMD {
      37             : 
      38             : PLUMED_REGISTER_ACTION(ActionToPutData,"PUT")
      39             : 
      40        7118 : void ActionToPutData::registerKeywords(Keywords& keys) {
      41        7118 :   ActionForInterface::registerKeywords( keys );
      42       14236 :   keys.add("compulsory","SHAPE","0","the shape of the value that is being passed to PLUMED");
      43       14236 :   keys.add("compulsory","UNIT","the unit of the quantity that is being passed to PLUMED through this value.  Can be either number, energy, time, length, mass or charge");
      44       14236 :   keys.add("compulsory","FORCE_UNIT","default","the units to use for the force");
      45       14236 :   keys.add("compulsory","PERIODIC","if the value being passed to plumed is periodic then you should specify the periodicity of the function.  If the value "
      46             :            "is not periodic you must state this using PERIODIC=NO.  Positions are passed with PERIODIC=NO even though special methods are used "
      47             :            "to deal with pbc");
      48       14236 :   keys.addFlag("CONSTANT",false,"does this quantity not depend on time");
      49       14236 :   keys.addFlag("FROM_DOMAINS",false,"is this quantity passed through the domain decomposition object");
      50       14236 :   keys.addFlag("MUTABLE",false,"can plumed change the value of the pointer that is passed from the MD code");
      51        7118 :   keys.setValueDescription("the data that was passed from the MD code");
      52        7118 : }
      53             : 
      54        8318 : ActionToPutData::ActionToPutData(const ActionOptions&ao):
      55             :   Action(ao),
      56             :   ActionForInterface(ao),
      57        8318 :   noforce(false),
      58        8318 :   fixed(false),
      59        8318 :   from_domains(false),
      60        8318 :   resetable(false),
      61        8318 :   dataCanBeSet(true),
      62        8318 :   unit(n),
      63        8318 :   mydata(DataPassingObject::create(plumed.getRealPrecision()))
      64             : {
      65       15401 :   if( getName()!="ENERGY" && getName()!="PBC" ) {
      66       14166 :     std::vector<unsigned> shape; parseVector("SHAPE",shape);
      67        7083 :     if( shape.size()==1 && shape[0]==0 ) { shape.resize(0); addValue( shape ); }
      68        5995 :     else { addValue( shape ); }
      69             : 
      70        7083 :     std::string unitstr, funitstr; parse("UNIT",unitstr);
      71       14166 :     parse("FORCE_UNIT",funitstr); setUnit( unitstr, funitstr );
      72             : 
      73             :     // Now sort out period
      74       14166 :     std::vector<std::string> period; parseVector("PERIODIC",period);
      75        7083 :     if( period.size()==1 ) {
      76        7081 :       if( period[0]!="NO") error("input to PERIODIC keyword does not make sense");
      77        7081 :       setNotPeriodic();
      78           2 :     } else if( period.size()==2 ) setPeriodic( period[0], period[1] );
      79           0 :     else  error("input to PERIODIC keyword does not make sense");
      80             : 
      81       14166 :     parseFlag("CONSTANT",fixed); if( fixed ) { noforce=true; copyOutput(0)->setConstant(); }
      82       14166 :     parseFlag("FROM_DOMAINS",from_domains); parseFlag("MUTABLE",resetable);
      83        7083 :   }
      84        8318 : }
      85             : 
      86        8318 : void ActionToPutData::setUnit( const std::string& unitstr, const std::string& funitstr ) {
      87        8318 :   if( unitstr=="number" ) unit=n;
      88        8295 :   else if( unitstr=="energy" ) unit=e;
      89        8194 :   else if( unitstr=="length" ) unit=l;
      90        3414 :   else if( unitstr=="mass" ) unit=m;
      91        2219 :   else if( unitstr=="charge" ) unit=q;
      92        1024 :   else if( unitstr=="time" ) unit=t;
      93           0 :   else error( unitstr + " is not a valid input unit");
      94             :   // Set the force units
      95        8318 :   if( funitstr=="default" ) funit=d;
      96        1195 :   else if( funitstr=="energy" ) funit=eng;
      97           0 :   else error( funitstr + " is not a valid input force unit");
      98        8318 : }
      99             : 
     100        9612 : std::string ActionToPutData::getUnitName() const {
     101        9612 :   if( unit==e ) return "energy";
     102        9447 :   if( unit==l ) return "length";
     103        4535 :   if( unit==m ) return "mass";
     104        3307 :   if( unit==q ) return "charge";
     105        2079 :   if( unit==t ) return "time";
     106           0 :   plumed_error();
     107             : }
     108             : 
     109      451096 : void ActionToPutData::setStart( const std::string& name, const unsigned& sss) {
     110      451096 :   plumed_assert( name==getLabel() ); mydata->setStart(sss);
     111      451096 : }
     112             : 
     113      451096 : void ActionToPutData::setStride( const std::string& name, const unsigned& sss ) {
     114      451096 :   plumed_assert( name==getLabel() ); mydata->setStride(sss);
     115      451096 : }
     116             : 
     117        9632 : void ActionToPutData::updateUnits( DataPassingTools* passtools ) {
     118             :   // Don't need to do anythign if this is just a number
     119        9632 :   if( unit==n ) return ;
     120             : 
     121       19224 :   double vunits=passtools->getUnitConversion( getUnitName() );
     122        9612 :   mydata->setUnit(vunits); if( fixed && wasset ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
     123        9612 :   if( funit==eng ) mydata->setForceUnit( 1/passtools->getUnitConversion("energy"));
     124        8384 :   else if( funit==d ) mydata->setForceUnit(1/passtools->getUnitConversion("energy")*vunits);
     125             : }
     126             : 
     127     1932787 : bool ActionToPutData::setValuePointer( const std::string& name, const TypesafePtr & val ) {
     128     1932787 :   if( name!=getLabel() ) return false;
     129      452193 :   wasset=true; plumed_massert( dataCanBeSet, "set " + getLabel() + " cannot be set at this time");
     130      452184 :   if( !from_domains ) {
     131       97043 :     if( !resetable && getPntrToComponent(0)->getRank()==0 ) {
     132        5076 :       mydata->saveValueAsDouble( val );
     133        5076 :       if( fixed ) mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
     134       91967 :     } else mydata->setValuePointer(val,getPntrToComponent(0)->getShape(), !resetable);
     135      710282 :   } else mydata->setValuePointer(val,std::vector<unsigned>(), !resetable);
     136             :   return true;
     137             : }
     138             : 
     139      977057 : bool ActionToPutData::setForcePointer( const std::string& name, const TypesafePtr & val ) {
     140      977057 :   if( name!=getLabel() ) return false;
     141      282703 :   plumed_massert( dataCanBeSet, "force on " + getLabel() + " cannot be set at this time");
     142      282703 :   if( !from_domains ) mydata->setForcePointer(val,getPntrToComponent(0)->getShape());
     143      435756 :   else mydata->setForcePointer(val,std::vector<unsigned>());
     144             :   return true;
     145             : }
     146             : 
     147        1350 : void ActionToPutData::getLocalValues( std::vector<double>& vals ) const {
     148        1350 :   mydata->share_data( vals );
     149        1350 : }
     150             : 
     151       94006 : void ActionToPutData::wait() {
     152       94006 :   dataCanBeSet=false; if( fixed || !wasset ) { return; } plumed_assert( wasset );
     153       94006 :   mydata->share_data( 0, getPntrToValue()->getNumberOfValues(), getPntrToValue() );
     154             : }
     155             : 
     156      445330 : void ActionToPutData::apply() {
     157      445330 :   if( getPntrToValue()->forcesWereAdded() && !noforce ) {
     158      182000 :     if( getName()=="ENERGY" || getDependencies().size()==0 ) mydata->add_force( getPntrToValue() );
     159             :   }
     160      445330 : }
     161             : 
     162         150 : unsigned ActionToPutData::getNumberOfForcesToRescale() const {
     163         150 :   if( getName()!="ENERGY" || getDependencies().size()>0 ) return copyOutput(0)->getNumberOfValues();
     164           0 :   plumed_assert( getDependencies().size()==1 );
     165           0 :   plumed_assert(getDependencies()[0]); // needed for following calls, see #1046
     166           0 :   ActionForInterface* ai = getDependencies()[0]->castToActionForInterface();
     167           0 :   return ai->getNumberOfForcesToRescale();
     168             : }
     169             : 
     170         200 : void ActionToPutData::rescaleForces( const double& alpha ) {
     171         200 :   if( noforce ) return; wasscaled=true;
     172         150 :   mydata->rescale_force( getNumberOfForcesToRescale(), alpha, getPntrToValue() );
     173             : 
     174             : }
     175             : 
     176         798 : void ActionToPutData::writeBinary(std::ostream&o) {
     177         798 :   if(!fixed) getPntrToValue()->writeBinary(o);
     178         798 : }
     179             : 
     180         798 : void ActionToPutData::readBinary(std::istream&i) {
     181         798 :   if(!fixed) getPntrToValue()->readBinary(i);
     182         798 : }
     183             : 
     184             : }

Generated by: LCOV version 1.16