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 : #ifndef __PLUMED_core_ActionWithValue_h 23 : #define __PLUMED_core_ActionWithValue_h 24 : 25 : #include "Action.h" 26 : #include "Value.h" 27 : #include "tools/Exception.h" 28 : #include <vector> 29 : #include <memory> 30 : 31 : namespace PLMD { 32 : 33 : /** 34 : \ingroup MULTIINHERIT 35 : Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some derivatives. 36 : This is used for PLMD::Bias, PLMD::Colvar and PLMD::Function 37 : 38 : The vast majority of the PLMD::Action objects that are implemented in 39 : plumed calculate some quantity or a set of quantities. This could be 40 : the value of a CV, the value of a function or the potential due to a bias. 41 : PLMD::ActionWithValue provides the functionality for storing these quantities 42 : and (in tandem with PLMD::ActionWithArguments) the functionality for passing 43 : quantities between PLMD::Actions. When you are deciding what quantities 44 : your new PLMD::Action will need to store using PLMD::ActionWithValue you must 45 : ask yourself the following two questions: 46 : 47 : - Do I need to differentiate my output quantities 48 : - Is my PLMD::Action calculating a single thing or does the output have multiple components 49 : 50 : If the answer to the first of these questions is yes then you must setup your values 51 : you using either PLMD::ActionWithValue::addValueWithDerivatives() or 52 : PLMD::ActionWithValue::addComponentWithDerivatives. If the answer is no you 53 : can set up values using PLMD::ActionWithValue::addValue() or PLMD::ActionWithValue::addComponent(). 54 : The precise routine you use to setup your values will depend on your answer to the 55 : second question. As you are probably aware if the output of your PLMD::Action is a 56 : single quantity you can reference that quantity in the input file using the label of the 57 : PLMD::Action it was calculated in. If your action <b> outputs only one quantity </b> 58 : we call that quantity the <b> value </b> of the Action. To set the <b> value </b> and get pointers to it 59 : you should <b> use the set of routines that have the word value in the name </b>. If, by contrast, 60 : your PLMD::Action calculates multiple quantities then these quantities are referenced in input using the 61 : label.component syntax. We refer to these <b> multiple quantities </b> the <b> components </b> 62 : of the PLMD::Action. Perhaps unsurprisingly, when you manipulate the <b> components </b> of an 63 : PLMD::Action you should use <b> the routines with the word component in the name. </b> 64 : */ 65 : 66 : class ActionWithValue : 67 : public virtual Action { 68 : private: 69 : /// An array containing the values for this action 70 : std::vector<std::unique_ptr<Value>> values; 71 : /// Are we skipping the calculation of the derivatives 72 : bool noderiv; 73 : /// Are we using numerical derivatives to differentiate 74 : bool numericalDerivatives; 75 : /// Return the index for the component named name 76 : int getComponent( const std::string& name ) const; 77 : public: 78 : 79 : // -------- The action has one value only ---------------- // 80 : 81 : /// Add a value with the name label 82 : void addValue(); 83 : /// Add a value with the name label that has derivatives 84 : void addValueWithDerivatives(); 85 : /// Set your default value to have no periodicity 86 : void setNotPeriodic(); 87 : /// Set the value to be periodic with a particular domain 88 : void setPeriodic( const std::string& min, const std::string& max ); 89 : protected: 90 : /// Get a pointer to the default value 91 : Value* getPntrToValue(); 92 : /// Set the default value (the one without name) 93 : void setValue(const double& d); 94 : 95 : // -------- The action has multiple components ---------- // 96 : 97 : public: 98 : /// Add a value with a name like label.name 99 : void addComponent( const std::string& name ); 100 : /// Add a value with a name like label.name that has derivatives 101 : void addComponentWithDerivatives( const std::string& name ); 102 : /// Set your value component to have no periodicity 103 : void componentIsNotPeriodic( const std::string& name ); 104 : /// Set the value to be periodic with a particular domain 105 : void componentIsPeriodic( const std::string& name, const std::string& min, const std::string& max ); 106 : protected: 107 : /// Return a pointer to the component by index 108 : Value* getPntrToComponent(int i); 109 : /// Return a pointer to the value by name 110 : Value* getPntrToComponent(const std::string& name); 111 : public: 112 : explicit ActionWithValue(const ActionOptions&ao); 113 : ~ActionWithValue(); 114 : 115 : /// Register all the relevant keywords for the action 116 : static void registerKeywords( Keywords& keys ); 117 : /// Insist that numerical derivatives should always be used for an action and make this fact appear in the manual 118 : static void noAnalyticalDerivatives(Keywords& keys); 119 : /// Puts a message into the manual that the components always output 120 : static void componentsAreNotOptional(Keywords& keys); 121 : /// The components in the action will depend on the user 122 : static void useCustomisableComponents(Keywords& keys); 123 : /// Are we not calculating derivatives 124 : virtual bool doNotCalculateDerivatives() const ; 125 : /// Get the value of one of the components of the PLMD::Action 126 : double getOutputQuantity( const unsigned j ) const ; 127 : /// Get the value with a specific name (N.B. if there is no such value this returns zero) 128 : double getOutputQuantity( const std::string& name ) const ; 129 : 130 : // --- Routines for passing stuff to ActionWithArguments -- // 131 : 132 : /// Check if a value with a particular name is present. This is only used in PLMD::ActionWithArguments. 133 : /// You should not use it when manipulating components. 134 : bool exists( const std::string& name ) const; 135 : /// Return a pointer to the value with name (this is used to retrieve values in other PLMD::Actions) 136 : /// You should NEVER use this routine to refer to the components of your PLMD::Action. Use 137 : /// getPntrToComponent instead. 138 : Value* copyOutput( const std::string&name ) const; 139 : /// Return a pointer to the value with this number (this is used to retrieve values in other PLMD::Actions) 140 : /// You should NEVER use this routine to refer to the components of your PLMD::Action. Use 141 : /// getPntrToComponent instead. 142 : Value* copyOutput( const unsigned& n ) const; 143 : /// get a string that contains all the available components 144 : std::string getComponentsList( ) const ; 145 : /// get a vector that contains the label for all the components 146 : std::vector<std::string> getComponentsVector( ) const ; 147 : 148 : 149 : // -- Routines for everything else -- // 150 : 151 : /// Returns the number of values defined 152 : int getNumberOfComponents() const ; 153 : /// Clear the forces on the values 154 : void clearInputForces(); 155 : /// Clear the derivatives of values wrt parameters 156 : virtual void clearDerivatives(); 157 : /// Calculate the gradients and store them for all the values (need for projections) 158 : void setGradientsIfNeeded(); 159 : /// Set the value 160 : void setValue(Value*,double); 161 : /// Check if numerical derivatives should be used 162 : bool checkNumericalDerivatives() const override; 163 : /// This forces the class to use numerical derivatives 164 : void useNumericalDerivatives(); 165 : // These are things for using vectors of values as fields 166 0 : virtual void checkFieldsAllowed() { 167 0 : error("cannot use this action as a field"); 168 : } 169 : virtual unsigned getNumberOfDerivatives()=0; 170 : /// Activate the calculation of derivatives 171 : virtual void turnOnDerivatives(); 172 : }; 173 : 174 : inline 175 161174 : double ActionWithValue::getOutputQuantity(const unsigned j) const { 176 161174 : plumed_massert(j<values.size(),"index requested is out of bounds"); 177 161174 : return values[j]->get(); 178 : } 179 : 180 : inline 181 2795908 : double ActionWithValue::getOutputQuantity( const std::string& name ) const { 182 : std::string thename; 183 5591816 : thename=getLabel() + "." + name; 184 6510563 : for(unsigned i=0; i<values.size(); ++i) { 185 3804715 : if( values[i]->name==thename ) { 186 90060 : return values[i]->value; 187 : } 188 : } 189 : return 0.0; 190 : } 191 : 192 : inline 193 199083 : void ActionWithValue::setValue(const double& d) { 194 199083 : plumed_massert(values.size()==1, "cannot use setValue in multi-component actions"); 195 199083 : plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default"); 196 199083 : values[0]->set(d); 197 199083 : } 198 : 199 : inline 200 : int ActionWithValue::getNumberOfComponents() const { 201 145964 : return values.size(); 202 : } 203 : 204 : inline 205 2 : void ActionWithValue::useNumericalDerivatives() { 206 4 : plumed_massert( keywords.exists("NUMERICAL_DERIVATIVES"), "numerical derivatives are not permitted for this action" ); 207 2 : numericalDerivatives=true; 208 2 : } 209 : 210 : inline 211 1641816 : bool ActionWithValue::checkNumericalDerivatives() const { 212 1641860 : return numericalDerivatives; 213 : } 214 : 215 : inline 216 5924 : bool ActionWithValue::doNotCalculateDerivatives() const { 217 69225540 : return noderiv; 218 : } 219 : 220 : 221 : 222 : } 223 : 224 : #endif