LCOV - code coverage report
Current view: top level - core - Value.cpp (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 103 119 86.6 %
Date: 2024-10-11 08:09:47 Functions: 13 16 81.2 %

          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 "Value.h"
      23             : #include "ActionWithValue.h"
      24             : #include "ActionAtomistic.h"
      25             : #include "ActionWithArguments.h"
      26             : #include "ActionWithVirtualAtom.h"
      27             : #include "tools/Exception.h"
      28             : #include "Atoms.h"
      29             : #include "PlumedMain.h"
      30             : 
      31             : namespace PLMD {
      32             : 
      33     3561022 : Value::Value():
      34     3561022 :   action(NULL),
      35     3561022 :   value_set(false),
      36     3561022 :   value(0.0),
      37     3561022 :   inputForce(0.0),
      38     3561022 :   hasForce(false),
      39     3561022 :   hasDeriv(true),
      40     3561022 :   periodicity(unset),
      41     3561022 :   min(0.0),
      42     3561022 :   max(0.0),
      43     3561022 :   max_minus_min(0.0),
      44     3561022 :   inv_max_minus_min(0.0)
      45             : {
      46     3561022 : }
      47             : 
      48          18 : Value::Value(const std::string& name):
      49          18 :   action(NULL),
      50          18 :   value_set(false),
      51          18 :   value(0.0),
      52          18 :   inputForce(0.0),
      53          18 :   hasForce(false),
      54          18 :   name(name),
      55          18 :   hasDeriv(true),
      56          18 :   periodicity(unset),
      57          18 :   min(0.0),
      58          18 :   max(0.0),
      59          18 :   max_minus_min(0.0),
      60          18 :   inv_max_minus_min(0.0)
      61             : {
      62          18 : }
      63             : 
      64       48348 : Value::Value(ActionWithValue* av, const std::string& name, const bool withderiv):
      65       48348 :   action(av),
      66       48348 :   value_set(false),
      67       48348 :   value(0.0),
      68       48348 :   inputForce(0.0),
      69       48348 :   hasForce(false),
      70       48348 :   name(name),
      71       48348 :   hasDeriv(withderiv),
      72       48348 :   periodicity(unset),
      73       48348 :   min(0.0),
      74       48348 :   max(0.0),
      75       48348 :   max_minus_min(0.0),
      76       48348 :   inv_max_minus_min(0.0)
      77             : {
      78       48348 : }
      79             : 
      80     1183328 : void Value::setupPeriodicity() {
      81     1183328 :   if( min==0 && max==0 ) {
      82       31849 :     periodicity=notperiodic;
      83             :   } else {
      84     1151479 :     periodicity=periodic;
      85     1151479 :     max_minus_min=max-min;
      86     1151479 :     plumed_massert(max_minus_min>0, "your function has a very strange domain?");
      87     1151479 :     inv_max_minus_min=1.0/max_minus_min;
      88             :   }
      89     1183328 : }
      90             : 
      91     1664611 : bool Value::isPeriodic()const {
      92     1664611 :   plumed_massert(periodicity!=unset,"periodicity should be set");
      93     1664611 :   return periodicity==periodic;
      94             : }
      95             : 
      96      964774 : bool Value::applyForce(std::vector<double>& forces ) const {
      97      964774 :   if( !hasForce ) return false;
      98             :   plumed_dbg_massert( derivatives.size()==forces.size()," forces array has wrong size" );
      99      115220 :   const unsigned N=derivatives.size();
     100    48882393 :   for(unsigned i=0; i<N; ++i) forces[i]=inputForce*derivatives[i];
     101             :   return true;
     102             : }
     103             : 
     104     3528246 : void Value::setNotPeriodic() {
     105     3528246 :   min=0; max=0; periodicity=notperiodic;
     106     3528246 : }
     107             : 
     108     1151479 : void Value::setDomain(const std::string& pmin,const std::string& pmax) {
     109     1151479 :   str_min=pmin;
     110     1151479 :   if( !Tools::convertNoexcept(str_min,min) ) action->error("could not convert period string " + str_min + " to real");
     111     1151479 :   str_max=pmax;
     112     1151479 :   if( !Tools::convertNoexcept(str_max,max) ) action->error("could not convert period string " + str_max + " to read");
     113     1151479 :   setupPeriodicity();
     114     1151479 : }
     115             : 
     116       27933 : void Value::getDomain(std::string&minout,std::string&maxout) const {
     117       27933 :   plumed_massert(periodicity==periodic,"function should be periodic");
     118       27933 :   minout=str_min;
     119       27933 :   maxout=str_max;
     120       27933 : }
     121             : 
     122          34 : void Value::getDomain(double&minout,double&maxout) const {
     123          34 :   plumed_massert(periodicity==periodic,"function should be periodic");
     124          34 :   minout=min;
     125          34 :   maxout=max;
     126          34 : }
     127             : 
     128         183 : void Value::setGradients() {
     129             :   // Can't do gradients if we don't have derivatives
     130         183 :   if( !hasDeriv ) return;
     131             :   gradients.clear();
     132         183 :   ActionAtomistic*aa=dynamic_cast<ActionAtomistic*>(action);
     133         183 :   ActionWithArguments*aw=dynamic_cast<ActionWithArguments*>(action);
     134         183 :   if(aa) {
     135         100 :     Atoms&atoms((aa->plumed).getAtoms());
     136        8092 :     for(unsigned j=0; j<aa->getNumberOfAtoms(); ++j) {
     137        7992 :       AtomNumber an=aa->getAbsoluteIndex(j);
     138        7992 :       if(atoms.isVirtualAtom(an)) {
     139             :         const ActionWithVirtualAtom* a=atoms.getVirtualAtomsAction(an);
     140          33 :         for(const auto & p : a->getGradients()) {
     141             : // controllare l'ordine del matmul:
     142          30 :           gradients[p.first]+=matmul(Vector(derivatives[3*j],derivatives[3*j+1],derivatives[3*j+2]),p.second);
     143             :         }
     144             :       } else {
     145       31956 :         for(unsigned i=0; i<3; i++) gradients[an][i]+=derivatives[3*j+i];
     146             :       }
     147             :     }
     148          83 :   } else if(aw) {
     149          83 :     std::vector<Value*> values=aw->getArguments();
     150         249 :     for(unsigned j=0; j<derivatives.size(); j++) {
     151        8174 :       for(const auto & p : values[j]->gradients) {
     152        8008 :         AtomNumber iatom=p.first;
     153        8008 :         gradients[iatom]+=p.second*derivatives[j];
     154             :       }
     155             :     }
     156           0 :   } else plumed_error();
     157             : }
     158             : 
     159         261 : double Value::projection(const Value& v1,const Value&v2) {
     160             :   double proj=0.0;
     161             :   const std::map<AtomNumber,Vector> & grad1(v1.gradients);
     162             :   const std::map<AtomNumber,Vector> & grad2(v2.gradients);
     163       16167 :   for(const auto & p1 : grad1) {
     164       15906 :     AtomNumber a=p1.first;
     165             :     const auto p2=grad2.find(a);
     166       15906 :     if(p2!=grad2.end()) {
     167        8224 :       proj+=dotProduct(p1.second,(*p2).second);
     168             :     }
     169             :   }
     170         261 :   return proj;
     171             : }
     172             : 
     173        4718 : ActionWithValue* Value::getPntrToAction() {
     174        4718 :   plumed_assert( action!=NULL );
     175        4718 :   return action;
     176             : }
     177             : 
     178           0 : void copy( const Value& val1, Value& val2 ) {
     179           0 :   unsigned nder=val1.getNumberOfDerivatives();
     180           0 :   if( nder!=val2.getNumberOfDerivatives() ) { val2.resizeDerivatives( nder ); }
     181             :   val2.clearDerivatives();
     182           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2.addDerivative( i, val1.getDerivative(i) );
     183             :   val2.set( val1.get() );
     184           0 : }
     185             : 
     186           0 : void copy( const Value& val1, Value* val2 ) {
     187           0 :   unsigned nder=val1.getNumberOfDerivatives();
     188           0 :   if( nder!=val2->getNumberOfDerivatives() ) { val2->resizeDerivatives( nder ); }
     189             :   val2->clearDerivatives();
     190           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
     191             :   val2->set( val1.get() );
     192           0 : }
     193             : 
     194           0 : void add( const Value& val1, Value* val2 ) {
     195           0 :   plumed_assert( val1.getNumberOfDerivatives()==val2->getNumberOfDerivatives() );
     196           0 :   for(unsigned i=0; i<val1.getNumberOfDerivatives(); ++i) val2->addDerivative( i, val1.getDerivative(i) );
     197           0 :   val2->set( val1.get() + val2->get() );
     198           0 : }
     199             : 
     200             : }

Generated by: LCOV version 1.15