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 : As is explained in the papers in the bibliography the potential energy can be biased with umbrella sampling. 36 : To print the potential energy from PLUMED you can use an input similar to the one below: 37 : 38 : ```plumed 39 : ene: ENERGY 40 : PRINT ARG=ene FILE=colvar 41 : ``` 42 : 43 : Notice that this CV is not available with all the MD codes. When 44 : it is available, and when replica exchange is also available, 45 : metadynamics applied to ENERGY can be used to decrease the 46 : number of required replicas. 47 : 48 : !!! caution "long tail corrections for energy" 49 : 50 : Some MD engines communicate to PLUMED the energy without the long tail corrections, 51 : leading to a small mismatch. If this is the case, use the energy from the MD engine for 52 : reweighting. See \issue{567}. 53 : 54 : !!! caution "replica exchange" 55 : 56 : Acceptance for replica exchange when ENERGY is biased 57 : is computed correctly only if all the replicas have the same 58 : potential energy function. This is for instance not true when 59 : using GROMACS with lambda replica exchange or with plumed-hrex branch. 60 : 61 : */ 62 : //+ENDPLUMEDOC 63 : 64 : 65 : class Energy : public ActionToPutData { 66 : private: 67 : /// This is used to sum the data 68 : DomainDecomposition* interface; 69 : /// This is the list of forces that must be scaled 70 : std::vector<ActionToPutData*> forces_to_scale; 71 : public: 72 : explicit Energy(const ActionOptions&); 73 : // active methods: 74 : static void registerKeywords( Keywords& keys ); 75 : void wait() override; 76 : void apply() override; 77 : }; 78 : 79 : 80 : PLUMED_REGISTER_ACTION(Energy,"ENERGY") 81 : 82 41 : Energy::Energy(const ActionOptions&ao): 83 : Action(ao), 84 : ActionToPutData(ao), 85 41 : interface(NULL) { 86 41 : plumed.setEnergyValue( getLabel() ); 87 41 : std::vector<std::size_t> shape; 88 41 : addValue( shape ); 89 41 : setNotPeriodic(); 90 82 : setUnit( "energy", "default" ); 91 41 : ActionToPutData* px=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posx"); 92 41 : plumed_assert(px); 93 41 : forces_to_scale.push_back(px); 94 41 : addDependency( px ); 95 41 : ActionToPutData* py=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posy"); 96 41 : plumed_assert(py); 97 41 : forces_to_scale.push_back(py); 98 41 : addDependency( py ); 99 41 : ActionToPutData* pz=plumed.getActionSet().selectWithLabel< ActionToPutData*>("posz"); 100 41 : plumed_assert(pz); 101 41 : forces_to_scale.push_back(pz); 102 41 : addDependency( pz ); 103 41 : ActionToPutData* bx=plumed.getActionSet().selectWithLabel< ActionToPutData*>("Box"); 104 41 : plumed_assert(bx); 105 41 : forces_to_scale.push_back(bx); 106 41 : addDependency( bx ); 107 41 : log<<" Bibliography "; 108 41 : log<<plumed.cite("Bartels and Karplus, J. Phys. Chem. B 102, 865 (1998)"); 109 41 : log<<plumed.cite("Bonomi and Parrinello, J. Comp. Chem. 30, 1615 (2009)"); 110 41 : log<<"\n"; 111 41 : } 112 : 113 45 : void Energy::registerKeywords( Keywords& keys ) { 114 45 : Action::registerKeywords( keys ); 115 90 : keys.setValueDescription("scalar","the internal energy"); 116 45 : keys.addDOI("10.1021/jp972280j"); 117 45 : keys.addDOI("10.1103/PhysRevLett.104.190601"); 118 45 : } 119 : 120 3999 : void Energy::wait() { 121 3999 : if( !interface ) { 122 41 : std::vector<DomainDecomposition*> allput=plumed.getActionSet().select<DomainDecomposition*>(); 123 41 : if( allput.size()>1 ) { 124 0 : warning("found more than one interface so don't know how to sum energy"); 125 : } 126 41 : interface = allput[0]; 127 : } 128 3999 : ActionToPutData::wait(); 129 3999 : if( interface ) { 130 3999 : interface->sumOverDomains( copyOutput(0) ); 131 : } 132 3999 : } 133 : 134 3999 : void Energy::apply() { 135 3999 : if( getPntrToValue()->forcesWereAdded() ) { 136 250 : for(unsigned i=0; i<forces_to_scale.size(); ++i) { 137 200 : forces_to_scale[i]->rescaleForces( 1.- getPntrToValue()->getForce(0)); 138 : } 139 : } 140 3999 : } 141 : 142 : } 143 : } 144 : 145 : 146 :