Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2019 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 :
30 : namespace PLMD {
31 :
32 : /**
33 : \ingroup MULTIINHERIT
34 : Used to create a PLMD::Action that has some scalar or vectorial output that may or may not have some derivatives.
35 : This is used for PLMD::Bias, PLMD::Colvar and PLMD::Function
36 :
37 : The vast majority of the PLMD::Action objects that are implemented in
38 : plumed calculate some quantity or a set of quantities. This could be
39 : the value of a CV, the value of a function or the potential due to a bias.
40 : PLMD::ActionWithValue provides the functionality for storing these quantities
41 : and (in tandem with PLMD::ActionWithArguments) the functionality for passing
42 : quantities between PLMD::Actions. When you are deciding what quantities
43 : your new PLMD::Action will need to store using PLMD::ActionWithValue you must
44 : ask yourself the following two questions:
45 :
46 : - Do I need to differentiate my output quantities
47 : - Is my PLMD::Action calculating a single thing or does the output have multiple components
48 :
49 : If the answer to the first of these questions is yes then you must setup your values
50 : you using either PLMD::ActionWithValue::addValueWithDerivatives() or
51 : PLMD::ActionWithValue::addComponentWithDerivatives. If the answer is no you
52 : can set up values using PLMD::ActionWithValue::addValue() or PLMD::ActionWithValue::addComponent().
53 : The precise routine you use to setup your values will depend on your answer to the
54 : second question. As you are probably aware if the output of your PLMD::Action is a
55 : single quantity you can reference that quantity in the input file using the label of the
56 : PLMD::Action it was calculated in. If your action <b> outputs only one quantity </b>
57 : we call that quantity the <b> value </b> of the Action. To set the <b> value </b> and get pointers to it
58 : you should <b> use the set of routines that have the word value in the name </b>. If, by contrast,
59 : your PLMD::Action calculates multiple quantities then these quantities are referenced in input using the
60 : label.component syntax. We refer to these <b> multiple quantities </b> the <b> components </b>
61 : of the PLMD::Action. Perhaps unsurprisingly, when you manipulate the <b> components </b> of an
62 : PLMD::Action you should use <b> the routines with the word component in the name. </b>
63 : */
64 :
65 : class ActionWithValue :
66 : public virtual Action
67 : {
68 : private:
69 : /// An array containing the values for this action
70 : std::vector<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 ;
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() { error("cannot use this action as a field"); }
167 : virtual unsigned getNumberOfDerivatives()=0;
168 : /// Activate the calculation of derivatives
169 : virtual void turnOnDerivatives();
170 : };
171 :
172 : inline
173 95503 : double ActionWithValue::getOutputQuantity(const unsigned j) const {
174 191006 : plumed_massert(j<values.size(),"index requested is out of bounds");
175 191006 : return values[j]->get();
176 : }
177 :
178 : inline
179 295486 : double ActionWithValue::getOutputQuantity( const std::string& name ) const {
180 1181944 : std::string thename; thename=getLabel() + "." + name;
181 2012009 : for(unsigned i=0; i<values.size(); ++i) {
182 516124 : if( values[i]->name==thename ) return values[i]->value;
183 : }
184 : return 0.0;
185 : }
186 :
187 : inline
188 126381 : void ActionWithValue::setValue(const double& d) {
189 126381 : plumed_massert(values.size()==1, "cannot use setValue in multi-component actions");
190 252762 : plumed_massert(values[0]->name==getLabel(), "The value you are trying to set is not the default");
191 126381 : values[0]->set(d);
192 126381 : }
193 :
194 : inline
195 : int ActionWithValue::getNumberOfComponents() const {
196 92525 : return values.size();
197 : }
198 :
199 : inline
200 2 : void ActionWithValue::useNumericalDerivatives() {
201 4 : plumed_massert( keywords.exists("NUMERICAL_DERIVATIVES"), "numerical derivatives are not permitted for this action" );
202 2 : numericalDerivatives=true;
203 2 : }
204 :
205 : inline
206 391603 : bool ActionWithValue::checkNumericalDerivatives() const {
207 391647 : return numericalDerivatives;
208 : }
209 :
210 : inline
211 5911 : bool ActionWithValue::doNotCalculateDerivatives() const {
212 64993784 : return noderiv;
213 : }
214 :
215 :
216 :
217 : }
218 :
219 : #endif
|