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/ActionToPutData.h" 23 : #include "core/DomainDecomposition.h" 24 : #include "core/PlumedMain.h" 25 : #include "core/ActionSet.h" 26 : #include "core/ActionRegister.h" 27 : 28 : namespace PLMD { 29 : namespace colvar { 30 : 31 : //+PLUMEDOC COLVAR ENERGY 32 : /* 33 : Calculate the total potential energy of the simulation box. 34 : 35 : The potential energy can be biased e.g. with umbrella sampling \cite bart-karp98jpcb or with well-tempered metadynamics \cite Bonomi:2009p17935. 36 : 37 : Notice that this CV could be unavailable with some MD code. When 38 : it is available, and when also replica exchange is available, 39 : metadynamics applied to ENERGY can be used to decrease the 40 : number of required replicas. 41 : 42 : \bug This \ref ENERGY does not include long tail corrections. 43 : Thus when using e.g. LAMMPS `"pair_modify tail yes"` or GROMACS `"DispCorr Ener"` (or `"DispCorr EnerPres"`), 44 : the potential energy from \ref ENERGY will be slightly different form the one of the MD code. 45 : You should still be able to use \ref ENERGY and then reweight your simulation with the correct MD energy value. 46 : 47 : \bug Acceptance for replica exchange when \ref ENERGY is biased 48 : is computed correctly only if all the replicas have the same 49 : potential energy function. This is for instance not true when 50 : using GROMACS with lambda replica exchange or with plumed-hrex branch. 51 : 52 : \par Examples 53 : 54 : The following input instructs plumed to print the energy of the system 55 : \plumedfile 56 : ene: ENERGY 57 : PRINT ARG=ene 58 : \endplumedfile 59 : 60 : */ 61 : //+ENDPLUMEDOC 62 : 63 : 64 : class Energy : public ActionToPutData { 65 : private: 66 : /// This is used to sum the data 67 : DomainDecomposition* interface; 68 : /// This is the list of forces that must be scaled 69 : std::vector<ActionToPutData*> forces_to_scale; 70 : public: 71 : explicit Energy(const ActionOptions&); 72 : // active methods: 73 : static void registerKeywords( Keywords& keys ); 74 : void wait() override; 75 : void apply() override; 76 : }; 77 : 78 : 79 : PLUMED_REGISTER_ACTION(Energy,"ENERGY") 80 : 81 40 : Energy::Energy(const ActionOptions&ao): 82 : Action(ao), 83 : ActionToPutData(ao), 84 40 : interface(NULL) 85 : { 86 40 : plumed.setEnergyValue( getLabel() ); std::vector<unsigned> shape; 87 80 : addValue( shape ); setNotPeriodic(); setUnit( "energy", "default" ); 88 40 : ActionToPutData* px=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posx"); 89 40 : plumed_assert(px); forces_to_scale.push_back(px); addDependency( px ); 90 40 : ActionToPutData* py=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posy"); 91 40 : plumed_assert(py); forces_to_scale.push_back(py); addDependency( py ); 92 40 : ActionToPutData* pz=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posz"); 93 40 : plumed_assert(pz); forces_to_scale.push_back(pz); addDependency( pz ); 94 40 : ActionToPutData* bx=plumed.getActionSet().selectWithLabel< ActionToPutData*>("Box"); 95 40 : plumed_assert(bx); forces_to_scale.push_back(bx); addDependency( bx ); 96 40 : log<<" Bibliography "; 97 80 : log<<plumed.cite("Bartels and Karplus, J. Phys. Chem. B 102, 865 (1998)"); 98 80 : log<<plumed.cite("Bonomi and Parrinello, J. Comp. Chem. 30, 1615 (2009)"); 99 40 : log<<"\n"; 100 40 : } 101 : 102 42 : void Energy::registerKeywords( Keywords& keys ) { 103 42 : Action::registerKeywords( keys ); 104 84 : keys.setValueDescription("scalar","the internal energy"); 105 42 : } 106 : 107 3989 : void Energy::wait() { 108 3989 : if( !interface ) { 109 40 : std::vector<DomainDecomposition*> allput=plumed.getActionSet().select<DomainDecomposition*>(); 110 40 : if( allput.size()>1 ) warning("found more than one interface so don't know how to sum energy"); 111 40 : interface = allput[0]; 112 : } 113 3989 : ActionToPutData::wait(); if( interface ) interface->sumOverDomains( copyOutput(0) ); 114 3989 : } 115 : 116 3989 : void Energy::apply() { 117 3989 : if( getPntrToValue()->forcesWereAdded() ) { 118 250 : for(unsigned i=0; i<forces_to_scale.size(); ++i) forces_to_scale[i]->rescaleForces( 1.- getPntrToValue()->getForce(0)); 119 : } 120 3989 : } 121 : 122 : } 123 : } 124 : 125 : 126 :