LCOV - code coverage report
Current view: top level - isdb - MetainferenceBase.h (source / functions) Hit Total Coverage
Test: plumed test coverage Lines: 76 78 97.4 %
Date: 2026-11-05 10:19:04 Functions: 11 11 100.0 %

          Line data    Source code
       1             : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
       2             :    Copyright (c) 2017-2026 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             : #ifndef __PLUMED_isdb_MetainferenceBase_h
      23             : #define __PLUMED_isdb_MetainferenceBase_h
      24             : 
      25             : #include "core/ActionWithValue.h"
      26             : #include "core/ActionAtomistic.h"
      27             : #include "core/ActionWithArguments.h"
      28             : #include "MetainferenceCore.h"
      29             : #include "core/PlumedMain.h"
      30             : #include "tools/Communicator.h"
      31             : #include <memory>
      32             : 
      33             : #define PLUMED_METAINF_INIT(ao) Action(ao),MetainferenceBase(ao)
      34             : 
      35             : namespace PLMD {
      36             : namespace isdb {
      37             : 
      38             : /**
      39             : \ingroup INHERIT
      40             : This is the abstract base class to use for implementing new ISDB Metainference actions, within it there is
      41             : information as to how to go about implementing a new Metainference action.
      42             : */
      43             : 
      44             : class MetainferenceBase :
      45             :   public ActionAtomistic,
      46             :   public ActionWithArguments,
      47             :   public ActionWithValue {
      48             : private:
      49             :   std::vector<double> forces;
      50             :   std::vector<double> forcesToApply;
      51             : 
      52             :   // activate metainference
      53             :   bool doscore_;
      54             :   // number of experimental data
      55             :   unsigned narg;
      56             :   // experimental data
      57             :   std::vector<double> parameters;
      58             :   // the Metainference algorithm
      59             :   std::unique_ptr<MetainferenceCore> core_;
      60             :   // output
      61             :   Value*   valueScore;
      62             :   // selector
      63             :   unsigned iselect;
      64             : 
      65             : public:
      66             :   static void registerKeywords( Keywords& keys );
      67             :   explicit MetainferenceBase(const ActionOptions&);
      68             :   ~MetainferenceBase();
      69             :   void Initialise(const unsigned input);
      70             :   void Selector();
      71             :   unsigned getNarg();
      72             :   void setNarg(const unsigned input);
      73             :   void setParameters(const std::vector<double>& input);
      74             :   void setParameter(const double input);
      75             :   void setCalcData(const unsigned index, const double datum);
      76             :   void setCalcData(const std::vector<double>& data);
      77             :   bool getDoScore();
      78             :   unsigned getWstride();
      79             :   double getScore();
      80             :   void setScore(const double score);
      81             :   void setDerivatives();
      82             :   double getMetaDer(const unsigned index);
      83             :   void writeStatus();
      84             :   void update() override;
      85             :   void turnOnDerivatives() override;
      86             :   unsigned getNumberOfDerivatives() override;
      87             :   void lockRequests() override;
      88             :   void unlockRequests() override;
      89             :   void calculateNumericalDerivatives( ActionWithValue* a ) override;
      90             :   void apply() override;
      91             :   void setArgDerivatives(Value *v, const double &d);
      92             :   void setAtomsDerivatives(Value*v, const unsigned i, const Vector&d);
      93             :   void setBoxDerivatives(Value*v, const Tensor&d);
      94             : };
      95             : 
      96             : inline
      97             : void MetainferenceBase::setNarg(const unsigned input) {
      98          83 :   narg = input;
      99             : }
     100             : 
     101             : inline
     102             : bool MetainferenceBase::getDoScore() {
     103       25327 :   return doscore_;
     104             : }
     105             : 
     106             : inline
     107             : unsigned MetainferenceBase::getWstride() {
     108             :   return core_->getWriteStride();
     109             : }
     110             : 
     111             : inline
     112             : unsigned MetainferenceBase::getNarg() {
     113             :   return narg;
     114             : }
     115             : 
     116             : inline
     117             : double MetainferenceBase::getMetaDer(const unsigned index) {
     118             :   return core_->getMetaDer(index);
     119             : }
     120             : 
     121             : inline
     122             : void MetainferenceBase::setCalcData(const unsigned index, const double datum) {
     123        4498 :   core_->data()[index] = datum;
     124        4498 : }
     125             : 
     126             : inline
     127             : void MetainferenceBase::setCalcData(const std::vector<double>& data) {
     128             :   std::vector<double>& calc_data=core_->data();
     129             :   for(unsigned i=0; i<data.size(); i++) {
     130             :     calc_data[i] = data[i];
     131             :   }
     132             : }
     133             : 
     134             : inline
     135          79 : void MetainferenceBase::setParameters(const std::vector<double>& input) {
     136         656 :   for(unsigned i=0; i<input.size(); i++) {
     137         577 :     parameters.push_back(input[i]);
     138             :   }
     139          79 : }
     140             : 
     141             : inline
     142             : void MetainferenceBase::setParameter(const double input) {
     143        2356 :   parameters.push_back(input);
     144        2356 : }
     145             : 
     146             : inline
     147        2503 : void MetainferenceBase::setScore(const double score) {
     148        2503 :   valueScore->set(score);
     149        2503 : }
     150             : 
     151             : inline
     152         254 : void MetainferenceBase::setDerivatives() {
     153             :   // Get appropriate number of derivatives
     154             :   // Derivatives are first for arguments and then for atoms
     155             :   unsigned nder;
     156         254 :   if( getNumberOfAtoms()>0 ) {
     157         254 :     nder = 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
     158             :   } else {
     159           0 :     nder = getNumberOfArguments();
     160             :   }
     161             : 
     162             :   // Resize all derivative arrays
     163         254 :   forces.resize( nder );
     164         254 :   forcesToApply.resize( nder );
     165       24396 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
     166       24142 :     getPntrToComponent(i)->resizeDerivatives(nder);
     167             :   }
     168         254 : }
     169             : 
     170             : inline
     171        3513 : void MetainferenceBase::turnOnDerivatives() {
     172        3513 :   ActionWithValue::turnOnDerivatives();
     173        3513 : }
     174             : 
     175             : inline
     176     2840758 : unsigned MetainferenceBase::getNumberOfDerivatives() {
     177     2840758 :   if( getNumberOfAtoms()>0 ) {
     178     2840758 :     return 3*getNumberOfAtoms() + 9 + getNumberOfArguments();
     179             :   }
     180           0 :   return getNumberOfArguments();
     181             : }
     182             : 
     183             : inline
     184        1323 : void MetainferenceBase::lockRequests() {
     185             :   ActionAtomistic::lockRequests();
     186             :   ActionWithArguments::lockRequests();
     187        1323 : }
     188             : 
     189             : inline
     190        1323 : void MetainferenceBase::unlockRequests() {
     191             :   ActionAtomistic::unlockRequests();
     192             :   ActionWithArguments::unlockRequests();
     193        1323 : }
     194             : 
     195             : inline
     196          75 : void MetainferenceBase::calculateNumericalDerivatives( ActionWithValue* a=NULL ) {
     197          75 :   if( getNumberOfArguments()>0 ) {
     198          48 :     ActionWithArguments::calculateNumericalDerivatives( a );
     199             :   }
     200          75 :   if( getNumberOfAtoms()>0 ) {
     201          75 :     Matrix<double> save_derivatives( getNumberOfComponents(), getNumberOfArguments() );
     202        1293 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
     203        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     204        1104 :         if(getPntrToComponent(j)->hasDerivatives()) {
     205          48 :           save_derivatives(j,i)=getPntrToComponent(j)->getDerivative(i);
     206             :         }
     207             :       }
     208             :     }
     209          75 :     calculateAtomicNumericalDerivatives( a, getNumberOfArguments() );
     210        1293 :     for(unsigned j=0; j<getNumberOfComponents(); ++j) {
     211        2322 :       for(unsigned i=0; i<getNumberOfArguments(); ++i) {
     212        1104 :         if(getPntrToComponent(j)->hasDerivatives()) {
     213          48 :           getPntrToComponent(j)->addDerivative( i, save_derivatives(j,i) );
     214             :         }
     215             :       }
     216             :     }
     217             :   }
     218          75 : }
     219             : 
     220             : inline
     221        1323 : void MetainferenceBase::apply() {
     222             :   bool wasforced=false;
     223        1323 :   forcesToApply.assign(forcesToApply.size(),0.0);
     224       42962 :   for(unsigned i=0; i<getNumberOfComponents(); ++i) {
     225       41639 :     if( getPntrToComponent(i)->applyForce( forces ) ) {
     226             :       wasforced=true;
     227    42521908 :       for(unsigned ii=0; ii<forces.size(); ++ii) {
     228    42513493 :         forcesToApply[ii]+=forces[ii];
     229             :       }
     230             :     }
     231             :   }
     232        1323 :   if( wasforced ) {
     233         865 :     unsigned ind=0;
     234         865 :     addForcesOnArguments( 0, forcesToApply, ind );
     235         865 :     if( getNumberOfAtoms()>0 ) {
     236         865 :       setForcesOnAtoms( forcesToApply, ind );
     237             :     }
     238             :   }
     239        1323 : }
     240             : 
     241             : inline
     242             : void MetainferenceBase::setArgDerivatives(Value *v, const double &d) {
     243             :   v->addDerivative(0,d);
     244             : }
     245             : 
     246             : inline
     247     2868730 : void MetainferenceBase::setAtomsDerivatives(Value*v, const unsigned i, const Vector&d) {
     248     2868730 :   const unsigned noa=getNumberOfArguments();
     249     2868730 :   v->addDerivative(noa+3*i+0,d[0]);
     250     2868730 :   v->addDerivative(noa+3*i+1,d[1]);
     251     2868730 :   v->addDerivative(noa+3*i+2,d[2]);
     252     2868730 : }
     253             : 
     254             : inline
     255       13344 : void MetainferenceBase::setBoxDerivatives(Value* v,const Tensor&d) {
     256       13344 :   const unsigned noa=getNumberOfArguments();
     257             :   const unsigned nat=getNumberOfAtoms();
     258       13344 :   v->addDerivative(noa+3*nat+0,d(0,0));
     259       13344 :   v->addDerivative(noa+3*nat+1,d(0,1));
     260       13344 :   v->addDerivative(noa+3*nat+2,d(0,2));
     261       13344 :   v->addDerivative(noa+3*nat+3,d(1,0));
     262       13344 :   v->addDerivative(noa+3*nat+4,d(1,1));
     263       13344 :   v->addDerivative(noa+3*nat+5,d(1,2));
     264       13344 :   v->addDerivative(noa+3*nat+6,d(2,0));
     265       13344 :   v->addDerivative(noa+3*nat+7,d(2,1));
     266       13344 :   v->addDerivative(noa+3*nat+8,d(2,2));
     267       13344 : }
     268             : 
     269             : 
     270             : }
     271             : }
     272             : 
     273             : #endif
     274             : 

Generated by: LCOV version 1.16