Line data Source code
1 : /* +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 : Copyright (c) 2016-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 : #include "ActionWithAveraging.h"
23 : #include "core/PlumedMain.h"
24 : #include "core/ActionSet.h"
25 :
26 : namespace PLMD {
27 : namespace vesselbase {
28 :
29 65 : void ActionWithAveraging::registerKeywords( Keywords& keys ) {
30 65 : Action::registerKeywords( keys ); ActionPilot::registerKeywords( keys ); ActionAtomistic::registerKeywords( keys );
31 65 : ActionWithArguments::registerKeywords( keys ); ActionWithValue::registerKeywords( keys ); ActionWithVessel::registerKeywords( keys );
32 65 : keys.add("compulsory","STRIDE","1","the frequency with which the data should be collected and added to the quantity being averaged");
33 : keys.add("compulsory","CLEAR","0","the frequency with which to clear all the accumulated data. The default value "
34 65 : "of 0 implies that all the data will be used and that the grid will never be cleared");
35 65 : keys.add("optional","LOGWEIGHTS","list of actions that calculates log weights that should be used to weight configurations when calculating averages");
36 65 : keys.add("compulsory","NORMALIZATION","true","This controls how the data is normalized it can be set equal to true, false or ndata. The differences between these options are explained in the manual page for \\ref HISTOGRAM");
37 65 : keys.remove("NUMERICAL_DERIVATIVES");
38 65 : }
39 :
40 53 : ActionWithAveraging::ActionWithAveraging( const ActionOptions& ao ):
41 : Action(ao),
42 : ActionPilot(ao),
43 : ActionAtomistic(ao),
44 : ActionWithArguments(ao),
45 : ActionWithValue(ao),
46 : ActionWithVessel(ao),
47 : myaverage(NULL),
48 : useRunAllTasks(false),
49 : clearstride(0),
50 53 : lweight(0),cweight(0)
51 : {
52 53 : if( keywords.exists("CLEAR") ) {
53 48 : parse("CLEAR",clearstride);
54 48 : if( clearstride>0 ) {
55 12 : if( clearstride%getStride()!=0 ) error("CLEAR parameter must be a multiple of STRIDE");
56 12 : log.printf(" clearing grid every %u steps \n",clearstride);
57 : }
58 : }
59 53 : if( keywords.exists("LOGWEIGHTS") ) {
60 48 : std::vector<std::string> wwstr; parseVector("LOGWEIGHTS",wwstr);
61 48 : if( wwstr.size()>0 ) log.printf(" reweighting using weights from ");
62 96 : std::vector<Value*> arg( getArguments() );
63 54 : for(unsigned i=0; i<wwstr.size(); ++i) {
64 6 : ActionWithValue* val = plumed.getActionSet().selectWithLabel<ActionWithValue*>(wwstr[i]);
65 6 : if( !val ) error("could not find value named");
66 6 : weights.push_back( val->copyOutput(val->getLabel()) );
67 6 : arg.push_back( val->copyOutput(val->getLabel()) );
68 6 : log.printf("%s ",wwstr[i].c_str() );
69 : }
70 48 : if( wwstr.size()>0 ) log.printf("\n");
71 42 : else log.printf(" weights are all equal to one\n");
72 96 : requestArguments( arg );
73 : }
74 53 : if( keywords.exists("NORMALIZATION") ) {
75 48 : std::string normstr; parse("NORMALIZATION",normstr);
76 48 : if( normstr=="true" ) normalization=t;
77 24 : else if( normstr=="false" ) normalization=f;
78 15 : else if( normstr=="ndata" ) normalization=ndata;
79 0 : else error("invalid instruction for NORMALIZATION flag should be true, false, or ndata");
80 : }
81 53 : }
82 :
83 45 : void ActionWithAveraging::setAveragingAction( AveragingVessel* av_vessel, const bool& usetasks ) {
84 45 : myaverage=av_vessel; addVessel( myaverage );
85 45 : useRunAllTasks=usetasks; resizeFunctions();
86 45 : }
87 :
88 1478 : void ActionWithAveraging::lockRequests() {
89 1478 : ActionAtomistic::lockRequests();
90 1478 : ActionWithArguments::lockRequests();
91 1478 : }
92 :
93 1478 : void ActionWithAveraging::unlockRequests() {
94 1478 : ActionAtomistic::unlockRequests();
95 1478 : ActionWithArguments::unlockRequests();
96 1478 : }
97 :
98 0 : void ActionWithAveraging::calculateNumericalDerivatives(PLMD::ActionWithValue*) {
99 0 : error("not possible to compute numerical derivatives for this action");
100 0 : }
101 :
102 1479 : void ActionWithAveraging::update() {
103 2958 : if( (clearstride!=1 && getStep()==0) || !onStep() ) return;
104 : // Clear if it is time to reset
105 1402 : if( myaverage ) {
106 109 : if( myaverage->wasreset() ) clearAverage();
107 : }
108 : // Calculate the weight for all reweighting
109 1402 : if ( weights.size()>0 ) {
110 207 : double sum=0; for(unsigned i=0; i<weights.size(); ++i) sum+=weights[i]->get();
111 207 : lweight=sum; cweight = exp( sum );
112 : } else {
113 1195 : lweight=0; cweight=1.0;
114 : }
115 : // Prepare to do the averaging
116 1402 : prepareForAveraging();
117 : // Run all the tasks (if required
118 1402 : if( useRunAllTasks ) runAllTasks();
119 : // This the averaging if it is not done using task list
120 1320 : else performOperations( true );
121 : // Update the norm
122 1402 : double normt = cweight; if( normalization==ndata ) normt = 1;
123 1402 : if( myaverage ) myaverage->setNorm( normt + myaverage->getNorm() );
124 : // Finish the averaging
125 1402 : finishAveraging();
126 : // By resetting here we are ensuring that the grid will be cleared at the start of the next step
127 1402 : if( myaverage ) {
128 109 : if( getStride()==0 || (clearstride>0 && getStep()%clearstride==0) ) myaverage->reset();
129 : }
130 : }
131 :
132 79 : void ActionWithAveraging::clearAverage() { plumed_assert( myaverage->wasreset() ); myaverage->clear(); }
133 :
134 0 : void ActionWithAveraging::performOperations( const bool& from_update ) { plumed_error(); }
135 :
136 :
137 : }
138 4821 : }
|