Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2011-2018 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/ActionPilot.h"
23 : #include "core/ActionWithValue.h"
24 : #include "core/ActionWithArguments.h"
25 : #include "core/ActionRegister.h"
26 : #include "tools/File.h"
27 :
28 : using namespace std;
29 :
30 : namespace PLMD {
31 : namespace generic {
32 :
33 : //+PLUMEDOC PRINTANALYSIS DUMPDERIVATIVES
34 : /*
35 : Dump the derivatives with respect to the input parameters for one or more objects (generally CVs, functions or biases).
36 :
37 : For a CV this line in input instructs plumed to print the derivative of the CV with respect to the atom positions
38 : and the cell vectors (virial-like form). In contrast, for a function or bias the derivative with respect to the input "CVs"
39 : will be output. This command is most often used to test whether or not analytic derivatives have been implemented correctly. This
40 : can be done by outputting the derivatives calculated analytically and numerically. You can control the buffering of output using the \ref FLUSH keyword.
41 :
42 : \par Examples
43 :
44 : The following input instructs plumed to write a file called deriv that contains both the
45 : analytical and numerical derivatives of the distance between atoms 1 and 2.
46 : \verbatim
47 : DISTANCE ATOM=1,2 LABEL=distance
48 : DISTANCE ATOM=1,2 LABEL=distanceN NUMERICAL_DERIVATIVES
49 : DUMPDERIVATIVES ARG=distance,distanceN STRIDE=1 FILE=deriv
50 : \endverbatim
51 :
52 : (See also \ref DISTANCE)
53 :
54 : */
55 : //+ENDPLUMEDOC
56 :
57 : class DumpDerivatives :
58 : public ActionPilot,
59 : public ActionWithArguments
60 : {
61 : string file;
62 : string fmt;
63 : OFile of;
64 : public:
65 9725 : void calculate() {}
66 : explicit DumpDerivatives(const ActionOptions&);
67 : static void registerKeywords(Keywords& keys);
68 9695 : void apply() {}
69 : void update();
70 : ~DumpDerivatives();
71 : };
72 :
73 2677 : PLUMED_REGISTER_ACTION(DumpDerivatives,"DUMPDERIVATIVES")
74 :
75 155 : void DumpDerivatives::registerKeywords(Keywords& keys) {
76 155 : Action::registerKeywords(keys);
77 155 : ActionPilot::registerKeywords(keys);
78 155 : ActionWithArguments::registerKeywords(keys);
79 155 : keys.use("ARG");
80 155 : keys.add("compulsory","STRIDE","1","the frequency with which the derivatives should be output");
81 155 : keys.add("compulsory","FILE","the name of the file on which to output the derivatives");
82 155 : keys.add("compulsory","FMT","%15.10f","the format with which the derivatives should be output");
83 155 : keys.use("RESTART");
84 155 : keys.use("UPDATE_FROM");
85 155 : keys.use("UPDATE_UNTIL");
86 155 : }
87 :
88 154 : DumpDerivatives::DumpDerivatives(const ActionOptions&ao):
89 : Action(ao),
90 : ActionPilot(ao),
91 : ActionWithArguments(ao),
92 154 : fmt("%15.10f")
93 : {
94 154 : parse("FILE",file);
95 154 : if( file.length()==0 ) error("name of output file was not specified");
96 154 : parse("FMT",fmt);
97 154 : fmt=" "+fmt;
98 154 : of.link(*this);
99 154 : of.open(file);
100 154 : log.printf(" on file %s\n",file.c_str());
101 154 : log.printf(" with format %s\n",fmt.c_str());
102 154 : unsigned nargs=getNumberOfArguments();
103 154 : if( nargs==0 ) error("no arguments specified");
104 154 : (getPntrToArgument(0)->getPntrToAction())->turnOnDerivatives();
105 154 : unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
106 154 : if( npar==0 ) error("one or more arguments has no derivatives");
107 478 : for(unsigned i=1; i<nargs; i++) {
108 324 : (getPntrToArgument(i)->getPntrToAction())->turnOnDerivatives();
109 324 : if( npar!=getPntrToArgument(i)->getNumberOfDerivatives() ) error("the number of derivatives must be the same in all values being dumped");
110 : }
111 154 : checkRead();
112 154 : }
113 :
114 :
115 9695 : void DumpDerivatives::update() {
116 9695 : unsigned npar=getPntrToArgument(0)->getNumberOfDerivatives();
117 556769 : for(unsigned ipar=0; ipar<npar; ipar++) {
118 547074 : of.fmtField(" %f");
119 547074 : of.printField("time",getTime());
120 547074 : of.printField("parameter",(int)ipar);
121 2976243 : for(unsigned i=0; i<getNumberOfArguments(); i++) {
122 2429169 : of.fmtField(fmt);
123 2429169 : of.printField(getPntrToArgument(i)->getName(),getPntrToArgument(i)->getDerivative(ipar) );
124 : }
125 547074 : of.printField();
126 : }
127 9695 : }
128 :
129 462 : DumpDerivatives::~DumpDerivatives() {
130 462 : }
131 :
132 : }
133 :
134 :
135 2523 : }
|